Skip to main content
Glama
longngo192

Google Cloud Docs MCP Server

by longngo192

search_google_cloud_docs

Search Google Cloud documentation to find configuration guides, best practices, and troubleshooting steps for GCP services like Compute Engine, Cloud Storage, BigQuery, and Kubernetes.

Instructions

Search Google Cloud documentation with any free-form query. Returns relevant documentation with actual content.

WHEN TO USE: ALWAYS use this tool when the user asks about Google Cloud Platform (GCP) services, configurations, best practices, or how-to questions. This is the PRIMARY tool for GCP-related queries.

TRIGGERS - Use this tool when user asks about:

  • Any GCP service (Compute Engine, Cloud Storage, BigQuery, Cloud SQL, GKE, Cloud Run, IAM, VPC, etc.)

  • Configuration questions ("how to configure...", "how to setup...")

  • Best practices for GCP services

  • Troubleshooting GCP issues

  • Cross-project or cross-account scenarios

  • Security, encryption, permissions in GCP

  • Networking in GCP (VPC, peering, firewall, load balancer)

  • Database configurations (Cloud SQL HA, replicas, backups)

  • Container orchestration (GKE autoscaling, node pools)

  • Serverless (Cloud Run, Cloud Functions environment variables)

INPUT:

  • query (required): Free-form search query in natural language

  • product (optional): Filter by specific GCP product

EXAMPLE QUERIES:

  • "how to share encrypted bucket cross account"

  • "vpc peering between two projects"

  • "cloud sql high availability setup"

  • "gke autoscaling configuration"

  • "bigquery partition table"

  • "cloud run environment variables"

  • "iam service account impersonation"

  • "cloud storage cmek encryption"

  • "gke workload identity"

OUTPUT: Returns JSON with:

  • query: Original search query

  • totalResults: Number of results found

  • results: Array of top 3 docs with full content (title, url, content)

  • otherRelatedDocs: Additional related documentation URLs

SUPPORTED TOPICS (80+ mappings):

  • Storage & Encryption: encrypt, bucket, cmek, kms, customer managed, object storage

  • IAM & Security: iam, role, service account, impersonation, workload identity

  • Networking: vpc, peering, shared vpc, firewall, load balancer, dns, nat, private access

  • Database: cloud sql, high availability, mysql, postgres, replica, failover

  • BigQuery: partition, cluster, materialized view, schedule

  • GKE: gke, autoscaling, node pool, horizontal pod autoscaler, helm

  • Serverless: cloud run, environment variable, cloud function, deploy

  • Container: docker, artifact registry, cloud build

  • Pub/Sub: pubsub, topic, subscription

  • Data Processing: dataflow, dataproc, composer, airflow, spark

  • Monitoring: logging, monitoring, metric, alert, dashboard, trace

  • Infrastructure: terraform, deployment manager, gcloud

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesFree-form search query in natural language (e.g., 'how to share encrypted bucket cross account', 'vpc peering between projects', 'cloud sql high availability')
productNoOptional: Filter by Google Cloud product (e.g., 'compute', 'storage', 'bigquery', 'kubernetes', 'sql', 'run')

Implementation Reference

  • Primary handler function implementing the search_google_cloud_docs tool. Performs Google search targeted at cloud.google.com, fallback to direct Cloud search, generates fallback paths from extensive topic mappings, scores relevance, fetches and extracts content from top 3 results.
    async function searchGoogleCloudDocs(
      query: string,
      product?: string
    ): Promise<string> {
      const results: {
        url: string;
        title?: string;
        snippet?: string;
        content?: string;
        error?: string;
      }[] = [];
    
      const queryLower = query.toLowerCase();
    
      // Step 1: Try to search using Google
      let searchResults = await searchGoogleForCloudDocs(query, product);
    
      // Step 2: If no results, try direct Google Cloud search
      if (searchResults.length === 0) {
        searchResults = await searchCloudGoogleDirect(query);
      }
    
      // Step 3: Build fallback paths from topic mappings (always, to supplement Google results)
      const potentialPaths: string[] = [];
    
      // Check for product keywords
      for (const [key, value] of Object.entries(GOOGLE_CLOUD_PRODUCTS)) {
        if (queryLower.includes(key) || queryLower.includes(value.name.toLowerCase())) {
          potentialPaths.push(value.docsPath);
          }
        }
    
        // Common topic mappings - more specific patterns first
        const topicMappings: Record<string, string[]> = {
          // Storage & Encryption
          encrypt: ["storage/docs/encryption", "kms/docs", "storage/docs/encryption/customer-managed-keys"],
          "customer managed": ["storage/docs/encryption/customer-managed-keys", "kms/docs/cmek"],
          share: ["storage/docs/access-control", "iam/docs/granting-changing-revoking-access"],
          "cross account": ["iam/docs/granting-changing-revoking-access", "storage/docs/access-control/cross-project"],
          "cross project": ["storage/docs/access-control/cross-project", "iam/docs/granting-changing-revoking-access"],
          bucket: ["storage/docs/creating-buckets", "storage/docs/access-control", "storage/docs"],
          "object storage": ["storage/docs", "storage/docs/objects"],
          permission: ["iam/docs/understanding-roles", "iam/docs/granting-changing-revoking-access"],
    
          // IAM & Security
          iam: ["iam/docs", "iam/docs/understanding-roles"],
          role: ["iam/docs/understanding-roles", "iam/docs/creating-custom-roles"],
          kms: ["kms/docs", "kms/docs/quickstart"],
          cmek: ["storage/docs/encryption/customer-managed-keys", "kms/docs/cmek"],
          "service account": ["iam/docs/service-accounts", "iam/docs/creating-managing-service-accounts"],
          impersonat: ["iam/docs/service-account-impersonation", "iam/docs/impersonating-service-accounts"],
          workload: ["iam/docs/workload-identity-federation", "kubernetes-engine/docs/how-to/workload-identity"],
    
          // Networking
          vpc: ["vpc/docs", "vpc/docs/shared-vpc", "vpc/docs/vpc-peering"],
          peering: ["vpc/docs/vpc-peering", "vpc/docs/using-vpc-peering"],
          "shared vpc": ["vpc/docs/shared-vpc", "vpc/docs/provisioning-shared-vpc"],
          firewall: ["vpc/docs/firewalls", "vpc/docs/using-firewalls"],
          "load balancer": ["load-balancing/docs", "load-balancing/docs/load-balancing-overview"],
          ingress: ["kubernetes-engine/docs/concepts/ingress", "load-balancing/docs/https"],
          ssl: ["load-balancing/docs/ssl-certificates", "certificate-manager/docs"],
          dns: ["dns/docs", "dns/docs/overview"],
          "private access": ["vpc/docs/private-google-access", "vpc/docs/configure-private-google-access"],
          "private service": ["vpc/docs/private-service-connect", "vpc/docs/configure-private-service-connect-services"],
          nat: ["vpc/docs/nat-service", "vpc/docs/using-nat"],
    
          // Database - Cloud SQL
          "cloud sql": ["sql/docs", "sql/docs/introduction"],
          "high availability": ["sql/docs/high-availability", "sql/docs/configure-ha"],
          ha: ["sql/docs/high-availability", "sql/docs/configure-ha"],
          mysql: ["sql/docs/mysql", "sql/docs/mysql/quickstart"],
          postgres: ["sql/docs/postgres", "sql/docs/postgres/quickstart"],
          "sql server": ["sql/docs/sqlserver", "sql/docs/sqlserver/quickstart"],
          replica: ["sql/docs/replication", "sql/docs/mysql/replication/create-replica"],
          failover: ["sql/docs/high-availability", "sql/docs/configure-ha"],
          "read replica": ["sql/docs/replication", "sql/docs/mysql/replication"],
          "point in time": ["sql/docs/backup-recovery/pitr", "sql/docs/mysql/backup-recovery/pitr"],
    
          // BigQuery
          bigquery: ["bigquery/docs", "bigquery/docs/introduction"],
          partition: ["bigquery/docs/partitioned-tables", "bigquery/docs/creating-partitioned-tables"],
          cluster: ["bigquery/docs/clustered-tables", "bigquery/docs/creating-clustered-tables"],
          "materialized view": ["bigquery/docs/materialized-views-intro", "bigquery/docs/materialized-views-create"],
          schedule: ["bigquery/docs/scheduling-queries", "bigquery/docs/scheduled-queries"],
    
          // GKE & Kubernetes
          gke: ["kubernetes-engine/docs", "kubernetes-engine/docs/concepts/kubernetes-engine-overview"],
          kubernetes: ["kubernetes-engine/docs", "kubernetes-engine/docs/quickstart"],
          autoscal: ["kubernetes-engine/docs/concepts/cluster-autoscaler", "kubernetes-engine/docs/how-to/cluster-autoscaler"],
          "node pool": ["kubernetes-engine/docs/concepts/node-pools", "kubernetes-engine/docs/how-to/node-pools"],
          "horizontal pod": ["kubernetes-engine/docs/concepts/horizontalpodautoscaler", "kubernetes-engine/docs/how-to/horizontal-pod-autoscaling"],
          helm: ["kubernetes-engine/docs/how-to/deploying-workloads-using-helm"],
    
          // Serverless
          "cloud run": ["run/docs", "run/docs/quickstarts"],
          "environment variable": ["run/docs/configuring/environment-variables", "functions/docs/configuring/env-var"],
          "cloud function": ["functions/docs", "functions/docs/quickstart"],
          "app engine": ["appengine/docs", "appengine/docs/standard"],
          deploy: ["run/docs/deploying", "functions/docs/deploy", "kubernetes-engine/docs/deploy-app-cluster"],
    
          // Container & Artifact
          container: ["run/docs", "kubernetes-engine/docs", "artifact-registry/docs"],
          docker: ["artifact-registry/docs/docker", "cloud-build/docs/building/build-containers"],
          "artifact registry": ["artifact-registry/docs", "artifact-registry/docs/docker"],
          "container registry": ["container-registry/docs"],
          "cloud build": ["cloud-build/docs", "cloud-build/docs/quickstart-build"],
    
          // Secret & Config
          secret: ["secret-manager/docs", "secret-manager/docs/quickstart"],
          "secret manager": ["secret-manager/docs", "secret-manager/docs/creating-and-accessing-secrets"],
          config: ["runtime-config/docs", "deployment-manager/docs"],
    
          // Pub/Sub & Messaging
          pubsub: ["pubsub/docs", "pubsub/docs/overview"],
          "pub/sub": ["pubsub/docs", "pubsub/docs/overview"],
          topic: ["pubsub/docs/create-topic", "pubsub/docs/admin"],
          subscription: ["pubsub/docs/subscriber", "pubsub/docs/create-subscription"],
    
          // Data Processing
          dataflow: ["dataflow/docs", "dataflow/docs/quickstarts"],
          dataproc: ["dataproc/docs", "dataproc/docs/quickstarts"],
          composer: ["composer/docs", "composer/docs/quickstart"],
          airflow: ["composer/docs", "composer/docs/concepts/airflow"],
          spark: ["dataproc/docs/spark", "dataproc/docs/concepts/spark"],
    
          // Monitoring & Logging
          logging: ["logging/docs", "logging/docs/view/overview"],
          log: ["logging/docs", "logging/docs/view/logs-viewer-interface"],
          monitoring: ["monitoring/docs", "monitoring/docs/monitoring-overview"],
          metric: ["monitoring/docs/metrics", "monitoring/docs/custom-metrics"],
          alert: ["monitoring/docs/alerting", "monitoring/docs/alerting/policies"],
          dashboard: ["monitoring/docs/dashboards", "monitoring/docs/dashboards/build-dashboards"],
          trace: ["trace/docs", "trace/docs/quickstart"],
    
          // Infrastructure
          terraform: ["docs/terraform", "docs/terraform/quickstart"],
          "deployment manager": ["deployment-manager/docs"],
          gcloud: ["sdk/gcloud/reference"],
          "cloud shell": ["shell/docs", "shell/docs/quickstart"],
    
          // Misc
          backup: ["storage/docs/lifecycle", "sql/docs/backup-recovery/backups"],
          snapshot: ["compute/docs/disks/create-snapshots", "compute/docs/disks/snapshots"],
          api: ["apis/docs/overview", "endpoints/docs"],
          authentication: ["docs/authentication", "iam/docs/authentication"],
          "cloud scheduler": ["scheduler/docs", "scheduler/docs/quickstart"],
          "cloud tasks": ["tasks/docs", "tasks/docs/quickstart"],
          budget: ["billing/docs/how-to/budgets", "billing/docs/how-to/budgets-programmatic"],
          cost: ["billing/docs/how-to/export-data-bigquery", "billing/docs/onboarding-checklist"],
        };
    
      for (const [keyword, paths] of Object.entries(topicMappings)) {
        if (queryLower.includes(keyword)) {
          potentialPaths.push(...paths);
        }
      }
    
      // Remove duplicates from potential paths
      const uniquePaths = [...new Set(potentialPaths)];
    
      // Add fallback paths to search results if not already present
      for (const path of uniquePaths) {
        const url = `https://cloud.google.com/${path}`;
        if (!searchResults.some(r => r.url === url)) {
          searchResults.push({
            url,
            title: path,
            snippet: "",
          });
        }
      }
    
      // Step 4: Score and sort results by relevance
      const scoredResults = searchResults.map(item => ({
        ...item,
        score: calculateRelevance(item.url, item.title, query)
      }));
    
      // Sort by score descending
      scoredResults.sort((a, b) => b.score - a.score);
    
      // Filter out results with very low relevance (likely unrelated)
      const relevantResults = scoredResults.filter(r => r.score >= 0 || scoredResults.indexOf(r) < 3);
    
      // Step 5: Fetch content from top results
      const urlsToFetch = relevantResults.slice(0, 3);
    
      for (const item of urlsToFetch) {
        try {
          // Extract path from URL
          const path = item.url.replace("https://cloud.google.com/", "").split("?")[0];
          const docResult = await fetchGoogleCloudDoc(path);
          const parsed = JSON.parse(docResult);
    
          if (parsed.error) {
            results.push({
              url: item.url,
              title: item.title,
              snippet: item.snippet,
              error: parsed.error,
            });
          } else {
            results.push({
              url: item.url,
              title: parsed.title || item.title,
              snippet: item.snippet,
              content: parsed.content,
            });
          }
        } catch (error) {
          results.push({
            url: item.url,
            title: item.title,
            snippet: item.snippet,
            error: error instanceof Error ? error.message : String(error),
          });
        }
      }
    
      // Include other search results without fetching content
      const otherResults = relevantResults.slice(3, 6).map((item) => ({
        url: item.url,
        title: item.title,
        snippet: item.snippet,
      }));
    
      return JSON.stringify({
        query: query,
        product: product || "all",
        totalResults: relevantResults.length,
        results: results,
        otherRelatedDocs: otherResults,
      });
    }
  • Input schema defining parameters: query (string, required), product (string, optional).
    inputSchema: {
      type: "object" as const,
      properties: {
        query: {
          type: "string",
          description:
            "Free-form search query in natural language (e.g., 'how to share encrypted bucket cross account', 'vpc peering between projects', 'cloud sql high availability')",
        },
        product: {
          type: "string",
          description:
            "Optional: Filter by Google Cloud product (e.g., 'compute', 'storage', 'bigquery', 'kubernetes', 'sql', 'run')",
        },
      },
      required: ["query"],
    },
  • src/index.ts:55-123 (registration)
    Tool registration in the MCP tools array with name, comprehensive description covering usage triggers, examples, output format, and supported GCP topics.
      {
        name: "search_google_cloud_docs",
        description: `Search Google Cloud documentation with any free-form query. Returns relevant documentation with actual content.
    
    **WHEN TO USE**: ALWAYS use this tool when the user asks about Google Cloud Platform (GCP) services, configurations, best practices, or how-to questions. This is the PRIMARY tool for GCP-related queries.
    
    **TRIGGERS** - Use this tool when user asks about:
    - Any GCP service (Compute Engine, Cloud Storage, BigQuery, Cloud SQL, GKE, Cloud Run, IAM, VPC, etc.)
    - Configuration questions ("how to configure...", "how to setup...")
    - Best practices for GCP services
    - Troubleshooting GCP issues
    - Cross-project or cross-account scenarios
    - Security, encryption, permissions in GCP
    - Networking in GCP (VPC, peering, firewall, load balancer)
    - Database configurations (Cloud SQL HA, replicas, backups)
    - Container orchestration (GKE autoscaling, node pools)
    - Serverless (Cloud Run, Cloud Functions environment variables)
    
    **INPUT**:
    - query (required): Free-form search query in natural language
    - product (optional): Filter by specific GCP product
    
    **EXAMPLE QUERIES**:
    - "how to share encrypted bucket cross account"
    - "vpc peering between two projects"
    - "cloud sql high availability setup"
    - "gke autoscaling configuration"
    - "bigquery partition table"
    - "cloud run environment variables"
    - "iam service account impersonation"
    - "cloud storage cmek encryption"
    - "gke workload identity"
    
    **OUTPUT**: Returns JSON with:
    - query: Original search query
    - totalResults: Number of results found
    - results: Array of top 3 docs with full content (title, url, content)
    - otherRelatedDocs: Additional related documentation URLs
    
    **SUPPORTED TOPICS** (80+ mappings):
    - Storage & Encryption: encrypt, bucket, cmek, kms, customer managed, object storage
    - IAM & Security: iam, role, service account, impersonation, workload identity
    - Networking: vpc, peering, shared vpc, firewall, load balancer, dns, nat, private access
    - Database: cloud sql, high availability, mysql, postgres, replica, failover
    - BigQuery: partition, cluster, materialized view, schedule
    - GKE: gke, autoscaling, node pool, horizontal pod autoscaler, helm
    - Serverless: cloud run, environment variable, cloud function, deploy
    - Container: docker, artifact registry, cloud build
    - Pub/Sub: pubsub, topic, subscription
    - Data Processing: dataflow, dataproc, composer, airflow, spark
    - Monitoring: logging, monitoring, metric, alert, dashboard, trace
    - Infrastructure: terraform, deployment manager, gcloud`,
        inputSchema: {
          type: "object" as const,
          properties: {
            query: {
              type: "string",
              description:
                "Free-form search query in natural language (e.g., 'how to share encrypted bucket cross account', 'vpc peering between projects', 'cloud sql high availability')",
            },
            product: {
              type: "string",
              description:
                "Optional: Filter by Google Cloud product (e.g., 'compute', 'storage', 'bigquery', 'kubernetes', 'sql', 'run')",
            },
          },
          required: ["query"],
        },
      },
  • MCP request handler switch case that parses arguments and invokes the searchGoogleCloudDocs implementation function.
    case "search_google_cloud_docs": {
      const { query, product } = args as { query: string; product?: string };
      const result = await searchGoogleCloudDocs(query, product);
      return {
        content: [{ type: "text", text: result }],
      };
    }
  • Key helper function used by the handler to fetch and parse individual documentation pages into structured markdown content.
    async function fetchGoogleCloudDoc(path: string): Promise<string> {
      const cleanPath = path.replace(/^\/+/, "").replace(/^cloud\.google\.com\//, "");
      const url = `${GOOGLE_CLOUD_API_DOCS_BASE}/${cleanPath}`;
    
      try {
        const response = await fetchWithTimeout(url);
    
        if (!response.ok) {
          return JSON.stringify({
            error: `Failed to fetch documentation: HTTP ${response.status}`,
            url: url,
            suggestion:
              "Please check the path and try again. Use 'list_google_cloud_products' to see available products.",
          });
        }
    
        const html = await response.text();
        const $ = cheerio.load(html);
    
        // Remove all unwanted elements
        $(
          "script, style, nav, header, footer, noscript, iframe, svg, img, " +
          ".devsite-nav, .devsite-book-nav, .devsite-footer, .devsite-header, " +
          ".devsite-breadcrumb-list, .devsite-page-title, .devsite-banner, " +
          ".devsite-collapsible-section, .devsite-toc, .devsite-article-meta, " +
          '[role="navigation"], [role="banner"], [aria-hidden="true"], ' +
          ".nocontent, .caution, .note, .warning, .tip, .key-point, " +
          ".buttons, .button-group, .cta, .feedback, .rating"
        ).remove();
    
        // Extract title from h1 or title tag
        const title =
          $("h1.devsite-page-title").first().text().trim() ||
          $("article h1").first().text().trim() ||
          $("h1").first().text().trim() ||
          $("title").text().replace(" | Google Cloud", "").trim() ||
          "Google Cloud Documentation";
    
        // Find main content area
        const mainContent =
          $(".devsite-article-body").html() ||
          $("article .body-content").html() ||
          $("article").html() ||
          $("main").html() ||
          $(".content").html();
    
        if (!mainContent) {
          return JSON.stringify({
            error: "Could not extract content from the page",
            url: url,
            rawTextPreview: $("body").text().replace(/\s+/g, " ").substring(0, 500),
          });
        }
    
        const $content = cheerio.load(mainContent);
    
        // Remove remaining unwanted elements from content
        $content(
          "nav, .devsite-nav, .devsite-toc, .nocontent, " +
          '[role="navigation"], [aria-hidden="true"]'
        ).remove();
    
        // Build structured content
        const sections: { heading: string; content: string; level: number }[] = [];
        let currentSection = { heading: title, content: "", level: 1 };
    
        // Process each element in order
        $content("h1, h2, h3, h4, h5, p, pre, ul, ol, table, blockquote, dl").each((_, elem) => {
          const $elem = $content(elem);
          const tagName = elem.type === "tag" ? elem.name : "";
    
          // Skip empty elements
          const text = $elem.text().trim();
          if (!text) return;
    
          // Skip navigation-like content
          if (text.includes("Documentation") && text.includes("Home") && text.length < 100) return;
          if (text.startsWith("Stay organized with collections")) return;
          if (text.startsWith("Save and categorize")) return;
    
          if (["h1", "h2", "h3", "h4", "h5"].includes(tagName)) {
            // Save previous section if it has content
            if (currentSection.content.trim()) {
              sections.push({ ...currentSection });
            }
            currentSection = {
              heading: text,
              content: "",
              level: parseInt(tagName.substring(1)),
            };
          } else if (tagName === "pre") {
            // Code blocks
            const codeText = $elem.text().trim();
            if (codeText && codeText.length > 5) {
              // Detect language from class
              const codeClass = $elem.find("code").attr("class") || "";
              const lang = codeClass.match(/language-(\w+)/)?.[1] || "";
              currentSection.content += `\n\`\`\`${lang}\n${codeText}\n\`\`\`\n`;
            }
          } else if (tagName === "table") {
            // Extract table data
            const rows: string[] = [];
            $elem.find("tr").each((_, tr) => {
              const cells: string[] = [];
              $content(tr).find("th, td").each((_, cell) => {
                cells.push($content(cell).text().trim());
              });
              if (cells.length > 0) {
                rows.push(cells.join(" | "));
              }
            });
            if (rows.length > 0) {
              currentSection.content += `\n| ${rows.join(" |\n| ")} |\n`;
            }
          } else if (tagName === "ul" || tagName === "ol") {
            // Lists
            const items: string[] = [];
            $elem.children("li").each((i, li) => {
              const itemText = $content(li).text().trim();
              if (itemText) {
                const prefix = tagName === "ol" ? `${i + 1}.` : "-";
                items.push(`${prefix} ${itemText}`);
              }
            });
            if (items.length > 0) {
              currentSection.content += `\n${items.join("\n")}\n`;
            }
          } else if (tagName === "dl") {
            // Definition lists
            $elem.find("dt").each((_, dt) => {
              const term = $content(dt).text().trim();
              const dd = $content(dt).next("dd").text().trim();
              if (term) {
                currentSection.content += `\n**${term}**: ${dd}\n`;
              }
            });
          } else if (tagName === "blockquote") {
            currentSection.content += `\n> ${text}\n`;
          } else {
            // Paragraphs and other text
            if (text.length > 10) {
              currentSection.content += `\n${text}\n`;
            }
          }
        });
    
        // Push last section
        if (currentSection.content.trim()) {
          sections.push(currentSection);
        }
    
        // Format output as markdown
        const formattedContent = sections
          .filter(s => s.content.trim().length > 0)
          .map((s) => {
            const headingPrefix = "#".repeat(Math.min(s.level, 4));
            return `${headingPrefix} ${s.heading}\n${s.content.trim()}`;
          })
          .join("\n\n");
    
        // Clean up excessive whitespace
        const cleanContent = formattedContent
          .replace(/\n{3,}/g, "\n\n")
          .trim();
    
        return JSON.stringify({
          title: title,
          url: url,
          content: cleanContent.substring(0, 20000),
          contentLength: cleanContent.length,
          truncated: cleanContent.length > 20000,
        });
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return JSON.stringify({
          error: `Failed to fetch documentation: ${errorMessage}`,
          url: url,
        });
      }
    }
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses behavioral traits: it returns 'actual content' (not just links), specifies the output format (JSON with fields like results array and otherRelatedDocs), mentions it returns 'top 3 docs' (implying ranking/limiting), and notes it handles 'free-form query in natural language'. However, it doesn't mention rate limits, authentication needs, or error handling, leaving some gaps for a search tool.

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

Conciseness3/5

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

The description is well-structured with sections (WHEN TO USE, TRIGGERS, INPUT, EXAMPLE QUERIES, OUTPUT, SUPPORTED TOPICS), but it is overly verbose. Sections like 'SUPPORTED TOPICS' with 80+ mappings and extensive trigger lists could be condensed, as some details (e.g., specific service names) are redundant with the clear usage guidelines. It front-loads key info but includes excessive examples that don't all earn their place.

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

Completeness4/5

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

Given the tool's complexity (search with natural language queries) and lack of annotations/output schema, the description is mostly complete. It covers purpose, usage, parameters, output format, and examples. However, without an output schema, it should ideally explain return values more thoroughly (e.g., content format, pagination), and it misses some behavioral aspects like error cases or performance hints, leaving minor gaps.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents both parameters (query and product) with examples. The description adds minimal value beyond the schema: it repeats that query is 'free-form search query in natural language' and product filters by 'specific GCP product', but doesn't provide additional syntax, format details, or constraints. This meets the baseline of 3 when schema does the heavy lifting.

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 the tool's purpose: 'Search Google Cloud documentation with any free-form query. Returns relevant documentation with actual content.' This specifies the verb (search), resource (Google Cloud documentation), and output (documentation with content). It distinguishes from sibling tools like 'fetch_google_cloud_doc' (likely fetches a specific doc) and 'get_api_reference' (focuses on API docs).

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?

The description includes an explicit 'WHEN TO USE' section stating this is the 'PRIMARY tool for GCP-related queries' and should 'ALWAYS' be used for GCP topics. It provides extensive 'TRIGGERS' with specific examples (e.g., services, configuration questions, best practices) and 'SUPPORTED TOPICS' with 80+ mappings, clearly differentiating when to use this over alternatives like 'list_google_cloud_products' (which likely lists products without searching content).

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/longngo192/gcpdoc-mcp'

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