Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added `functions.list_functions` as a MCP tool (#9369)
3 changes: 2 additions & 1 deletion src/mcp/tools/functions/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ServerTool } from "../../tool";

import { get_logs } from "./get_logs";
import { list_functions } from "./list_functions";

export const functionsTools: ServerTool[] = [get_logs];
export const functionsTools: ServerTool[] = [get_logs, list_functions];
58 changes: 58 additions & 0 deletions src/mcp/tools/functions/list_functions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { z } from "zod";

import { tool } from "../../tool";
import { mcpError, toContent } from "../../util";
import * as backend from "../../../deploy/functions/backend";
import { getErrMsg } from "../../../error";
import * as args from "../../../deploy/functions/args";

export const list_functions = tool(
"functions",
{
name: "list_functions",
description: "List all deployed functions in your Firebase project.",
inputSchema: z.object({}),
annotations: {
title: "List Deployed Functions",
readOnlyHint: true,
openWorldHint: true,
},
_meta: {
requiresAuth: true,
requiresProject: true,
},
},
async (_, { projectId }) => {
const context = {
projectId,
} as args.Context;

try {
// fetches info about all currently deployed functions for the project
const existing = await backend.existingBackend(context);
// extracts all the function endpoints and sorts them
const endpointsList = backend.allEndpoints(existing).sort(backend.compareFunctions);

// below format differs from Firebase CLI command output to be more suitable format for agents
const formattedList = endpointsList.map((endpoint) => ({
function: endpoint.id,
version: endpoint.platform === "gcfv2" ? "v2" : "v1",
trigger: backend.endpointTriggerType(endpoint),
location: endpoint.region,
memory: endpoint.availableMemoryMb || "---",
runtime: endpoint.runtime,
}));

if (!formattedList.length) {
return toContent([], {
contentPrefix: "No functions found in this project.\n\n",
});
}

return toContent(formattedList);
} catch (err) {
const errMsg = getErrMsg((err as any)?.original || err, "Failed to list functions.");

Check warning on line 54 in src/mcp/tools/functions/list_functions.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type

Check warning on line 54 in src/mcp/tools/functions/list_functions.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .original on an `any` value
return mcpError(errMsg);
}
},
);
Loading