gcp-billing-list-projects
Retrieve and manage all projects linked to a Google Cloud billing account by specifying the account name, pagination size, and token for comprehensive project visibility.
Instructions
List all projects associated with a specific Google Cloud billing account
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| billingAccountName | Yes | Billing account name (e.g., 'billingAccounts/123456-789ABC-DEF012') | |
| pageSize | No | Maximum number of projects to return (1-200) | |
| pageToken | No | Token for pagination to get next page of results |
Implementation Reference
- src/services/billing/tools.ts:200-293 (registration)Registration of the 'gcp-billing-list-projects' tool with input schema and inline handler. The handler uses getBillingClient() to create CloudBillingClient and calls listProjectBillingInfo to retrieve projects for the given billing account, formats the results as a Markdown table with pagination support."gcp-billing-list-projects", { title: "List Billing Account Projects", description: "List all projects associated with a specific Google Cloud billing account", inputSchema: { billingAccountName: z .string() .describe( "Billing account name (e.g., 'billingAccounts/123456-789ABC-DEF012')", ), pageSize: z .number() .min(1) .max(200) .default(50) .describe("Maximum number of projects to return (1-200)"), pageToken: z .string() .optional() .describe("Token for pagination to get next page of results"), }, }, async ({ billingAccountName, pageSize, pageToken }) => { try { const billingClient = getBillingClient(); logger.debug( `Listing projects for billing account: ${billingAccountName}`, ); const request: any = { name: billingAccountName, pageSize, }; if (pageToken) { request.pageToken = pageToken; } const [projects, nextPageToken] = await billingClient.listProjectBillingInfo(request); if (!projects || projects.length === 0) { return { content: [ { type: "text", text: `No projects found for billing account: ${billingAccountName}`, }, ], }; } let response = `# Projects for Billing Account\n\n`; response += `**Billing Account:** ${billingAccountName}\n`; response += `**Projects Found:** ${projects.length}\n\n`; response += "| Project ID | Billing Enabled | Project Name |\n"; response += "|------------|-----------------|-------------|\n"; for (const project of projects) { const projectId = project.name?.replace("projects/", "") || "Unknown"; const billingEnabled = project.billingEnabled ? "✅ Yes" : "❌ No"; const projectName = project.name || "Unknown"; response += `| ${projectId} | ${billingEnabled} | ${projectName} |\n`; } if (nextPageToken) { response += `\n**Next Page Token:** ${nextPageToken}\n`; response += `Use this token with the same tool to get the next page of results.\n`; } return { content: [ { type: "text", text: response, }, ], }; } catch (error: any) { logger.error( `Error listing projects for billing account: ${error.message}`, ); throw new GcpMcpError( `Failed to list projects for billing account: ${error.message}`, error.code || "UNKNOWN", error.status || 500, ); } }, );
- src/services/billing/tools.ts:223-292 (handler)The async handler function implementing the core logic of the tool. It takes billingAccountName, pageSize, and pageToken as input, calls the Google Cloud Billing API to list associated projects, handles pagination, formats the output as a Markdown table, and returns MCP content.async ({ billingAccountName, pageSize, pageToken }) => { try { const billingClient = getBillingClient(); logger.debug( `Listing projects for billing account: ${billingAccountName}`, ); const request: any = { name: billingAccountName, pageSize, }; if (pageToken) { request.pageToken = pageToken; } const [projects, nextPageToken] = await billingClient.listProjectBillingInfo(request); if (!projects || projects.length === 0) { return { content: [ { type: "text", text: `No projects found for billing account: ${billingAccountName}`, }, ], }; } let response = `# Projects for Billing Account\n\n`; response += `**Billing Account:** ${billingAccountName}\n`; response += `**Projects Found:** ${projects.length}\n\n`; response += "| Project ID | Billing Enabled | Project Name |\n"; response += "|------------|-----------------|-------------|\n"; for (const project of projects) { const projectId = project.name?.replace("projects/", "") || "Unknown"; const billingEnabled = project.billingEnabled ? "✅ Yes" : "❌ No"; const projectName = project.name || "Unknown"; response += `| ${projectId} | ${billingEnabled} | ${projectName} |\n`; } if (nextPageToken) { response += `\n**Next Page Token:** ${nextPageToken}\n`; response += `Use this token with the same tool to get the next page of results.\n`; } return { content: [ { type: "text", text: response, }, ], }; } catch (error: any) { logger.error( `Error listing projects for billing account: ${error.message}`, ); throw new GcpMcpError( `Failed to list projects for billing account: ${error.message}`, error.code || "UNKNOWN", error.status || 500, ); } },
- Helper function that creates and returns the CloudBillingClient instance used by the tool handler to make API calls.export function getBillingClient(): CloudBillingClient { return new CloudBillingClient({ projectId: process.env.GOOGLE_CLOUD_PROJECT, }); }
- Input schema using Zod for validating tool parameters: required billingAccountName, optional pageSize (default 50, range 1-200), optional pageToken for pagination.{ title: "List Billing Account Projects", description: "List all projects associated with a specific Google Cloud billing account", inputSchema: { billingAccountName: z .string() .describe( "Billing account name (e.g., 'billingAccounts/123456-789ABC-DEF012')", ), pageSize: z .number() .min(1) .max(200) .default(50) .describe("Maximum number of projects to return (1-200)"), pageToken: z .string() .optional() .describe("Token for pagination to get next page of results"), },