Skip to main content
Glama
krzko

Google Cloud MCP Server

by krzko

gcp-spanner-list-instances

List all Cloud Spanner instances in your Google Cloud project to manage database resources and configurations.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
_dummyNoNot used, just to ensure parameter compatibility

Implementation Reference

  • The handler function for the 'gcp-spanner-list-instances' tool. It determines the GCP project ID, creates a Spanner client, lists all instances, formats the results as a Markdown table with instance details (ID, state, config, nodes), and provides resource links for further exploration.
    async (_params, _extra) => {
      try {
        // First try to get the project ID from the state manager
        let projectId = stateManager.getCurrentProjectId();
    
        if (projectId) {
          logger.debug(`Got project ID from state manager: ${projectId}`);
        } else {
          // If not in state manager, try to get it from environment
          const envProjectId = process.env.GOOGLE_CLOUD_PROJECT;
    
          if (envProjectId) {
            projectId = envProjectId;
            logger.debug(`Got project ID from environment: ${projectId}`);
            // Store in state manager for future use
            await stateManager.setCurrentProjectId(projectId);
          } else {
            // If not in environment, try to get it from our function
            projectId = await getProjectId();
            logger.debug(`Got project ID from getProjectId: ${projectId}`);
          }
        }
    
        if (!projectId) {
          throw new Error(
            "Project ID could not be determined. Please set a project ID using the set-project-id tool.",
          );
        }
    
        // Create Spanner client with explicit project ID
        const spanner = new (await import("@google-cloud/spanner")).Spanner({
          projectId: projectId,
        });
    
        logger.debug(
          `Using Spanner client with explicit project ID: ${projectId} for list-spanner-instances`,
        );
    
        const [instances] = await spanner.getInstances();
    
        if (!instances || instances.length === 0) {
          return {
            content: [
              {
                type: "text",
                text: `# Spanner Instances\n\nProject: ${projectId}\n\nNo instances found in the project.`,
              },
            ],
          };
        }
    
        let markdown = `# Spanner Instances\n\nProject: ${projectId}\n\n`;
    
        // Table header
        markdown += "| Instance ID | State | Config | Nodes |\n";
        markdown += "|-------------|-------|--------|-------|\n";
    
        // Table rows
        for (const instance of instances) {
          const metadata = instance.metadata || {};
          markdown += `| ${instance.id || "unknown"} | ${metadata.state || "unknown"} | ${metadata.config?.split("/").pop() || "unknown"} | ${metadata.nodeCount || "unknown"} |\n`;
        }
    
        // Add resource links for further exploration
        markdown += "\n## Available Resources\n\n";
        markdown += `- All Instances: \`gcp-spanner://${projectId}/instances\`\n`;
    
        for (const instance of instances) {
          markdown += `- Databases in ${instance.id}: \`gcp-spanner://${projectId}/${instance.id}/databases\`\n`;
        }
    
        return {
          content: [
            {
              type: "text",
              text: markdown,
            },
          ],
        };
      } catch (error: any) {
        logger.error(
          `Error listing Spanner instances: ${error instanceof Error ? error.message : String(error)}`,
        );
        throw error;
      }
    },
  • The Zod input schema for the tool. It defines an optional dummy string parameter to ensure compatibility with MCP clients that expect an object parameter.
    {
      _dummy: z
        .string()
        .optional()
        .describe("Not used, just to ensure parameter compatibility"),
    },
  • The registration of the 'gcp-spanner-list-instances' tool using server.tool(), including the inline schema and handler function.
    // Tool to list instances
    server.tool(
      "gcp-spanner-list-instances",
      // Define an empty schema with a dummy parameter that's optional
      // This ensures compatibility with clients that expect an object parameter
      {
        _dummy: z
          .string()
          .optional()
          .describe("Not used, just to ensure parameter compatibility"),
      },
      async (_params, _extra) => {
        try {
          // First try to get the project ID from the state manager
          let projectId = stateManager.getCurrentProjectId();
    
          if (projectId) {
            logger.debug(`Got project ID from state manager: ${projectId}`);
          } else {
            // If not in state manager, try to get it from environment
            const envProjectId = process.env.GOOGLE_CLOUD_PROJECT;
    
            if (envProjectId) {
              projectId = envProjectId;
              logger.debug(`Got project ID from environment: ${projectId}`);
              // Store in state manager for future use
              await stateManager.setCurrentProjectId(projectId);
            } else {
              // If not in environment, try to get it from our function
              projectId = await getProjectId();
              logger.debug(`Got project ID from getProjectId: ${projectId}`);
            }
          }
    
          if (!projectId) {
            throw new Error(
              "Project ID could not be determined. Please set a project ID using the set-project-id tool.",
            );
          }
    
          // Create Spanner client with explicit project ID
          const spanner = new (await import("@google-cloud/spanner")).Spanner({
            projectId: projectId,
          });
    
          logger.debug(
            `Using Spanner client with explicit project ID: ${projectId} for list-spanner-instances`,
          );
    
          const [instances] = await spanner.getInstances();
    
          if (!instances || instances.length === 0) {
            return {
              content: [
                {
                  type: "text",
                  text: `# Spanner Instances\n\nProject: ${projectId}\n\nNo instances found in the project.`,
                },
              ],
            };
          }
    
          let markdown = `# Spanner Instances\n\nProject: ${projectId}\n\n`;
    
          // Table header
          markdown += "| Instance ID | State | Config | Nodes |\n";
          markdown += "|-------------|-------|--------|-------|\n";
    
          // Table rows
          for (const instance of instances) {
            const metadata = instance.metadata || {};
            markdown += `| ${instance.id || "unknown"} | ${metadata.state || "unknown"} | ${metadata.config?.split("/").pop() || "unknown"} | ${metadata.nodeCount || "unknown"} |\n`;
          }
    
          // Add resource links for further exploration
          markdown += "\n## Available Resources\n\n";
          markdown += `- All Instances: \`gcp-spanner://${projectId}/instances\`\n`;
    
          for (const instance of instances) {
            markdown += `- Databases in ${instance.id}: \`gcp-spanner://${projectId}/${instance.id}/databases\`\n`;
          }
    
          return {
            content: [
              {
                type: "text",
                text: markdown,
              },
            ],
          };
        } catch (error: any) {
          logger.error(
            `Error listing Spanner instances: ${error instanceof Error ? error.message : String(error)}`,
          );
          throw error;
        }
      },
    );
  • src/index.ts:170-170 (registration)
    Top-level registration call that invokes registerSpannerTools(server), which registers the Spanner tools including 'gcp-spanner-list-instances'.
    registerSpannerTools(server);

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/krzko/google-cloud-mcp'

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