Skip to content

Commit 5bac350

Browse files
brittanychotaeold
andauthored
Add MCP tool to list functions (#9369)
* add list_functions tool for mcp * adds list_function to index.ts * fix linting errors * switch readOnlyHint to true * Update src/mcp/tools/functions/list_functions.ts Co-authored-by: Daniel Lee <[email protected]> * Update src/mcp/tools/functions/list_functions.ts Co-authored-by: Daniel Lee <[email protected]> * update changelog * cleaned up formatting errors with prettier --------- Co-authored-by: Daniel Lee <[email protected]>
1 parent 6282bcf commit 5bac350

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Added `functions.list_functions` as a MCP tool (#9369)

src/mcp/tools/functions/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ServerTool } from "../../tool";
22

33
import { get_logs } from "./get_logs";
4+
import { list_functions } from "./list_functions";
45

5-
export const functionsTools: ServerTool[] = [get_logs];
6+
export const functionsTools: ServerTool[] = [get_logs, list_functions];
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { z } from "zod";
2+
3+
import { tool } from "../../tool";
4+
import { mcpError, toContent } from "../../util";
5+
import * as backend from "../../../deploy/functions/backend";
6+
import { getErrMsg } from "../../../error";
7+
import * as args from "../../../deploy/functions/args";
8+
9+
export const list_functions = tool(
10+
"functions",
11+
{
12+
name: "list_functions",
13+
description: "List all deployed functions in your Firebase project.",
14+
inputSchema: z.object({}),
15+
annotations: {
16+
title: "List Deployed Functions",
17+
readOnlyHint: true,
18+
openWorldHint: true,
19+
},
20+
_meta: {
21+
requiresAuth: true,
22+
requiresProject: true,
23+
},
24+
},
25+
async (_, { projectId }) => {
26+
const context = {
27+
projectId,
28+
} as args.Context;
29+
30+
try {
31+
// fetches info about all currently deployed functions for the project
32+
const existing = await backend.existingBackend(context);
33+
// extracts all the function endpoints and sorts them
34+
const endpointsList = backend.allEndpoints(existing).sort(backend.compareFunctions);
35+
36+
// below format differs from Firebase CLI command output to be more suitable format for agents
37+
const formattedList = endpointsList.map((endpoint) => ({
38+
function: endpoint.id,
39+
version: endpoint.platform === "gcfv2" ? "v2" : "v1",
40+
trigger: backend.endpointTriggerType(endpoint),
41+
location: endpoint.region,
42+
memory: endpoint.availableMemoryMb || "---",
43+
runtime: endpoint.runtime,
44+
}));
45+
46+
if (!formattedList.length) {
47+
return toContent([], {
48+
contentPrefix: "No functions found in this project.\n\n",
49+
});
50+
}
51+
52+
return toContent(formattedList);
53+
} catch (err) {
54+
const errMsg = getErrMsg((err as any)?.original || err, "Failed to list functions.");
55+
return mcpError(errMsg);
56+
}
57+
},
58+
);

0 commit comments

Comments
 (0)