Skip to content

Commit 4dd8137

Browse files
authored
[MCP] [Cleanup] Add an error handling catch for tool call (#8486)
1 parent 9f64df6 commit 4dd8137

File tree

9 files changed

+52
-66
lines changed

9 files changed

+52
-66
lines changed

src/mcp/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
ListToolsRequestSchema,
88
ListToolsResult,
99
} from "@modelcontextprotocol/sdk/types.js";
10+
import { mcpError } from "./util.js";
1011
import { ServerFeature } from "./types.js";
1112
import { tools } from "./tools/index.js";
1213
import { ServerTool } from "./tool.js";
@@ -104,7 +105,11 @@ export class FirebaseMcpServer {
104105
const tool = this.getTool(toolName);
105106
if (!tool) throw new Error(`Tool '${toolName}' could not be found.`);
106107

107-
return tool.fn(toolArgs, { projectId: await this.getProjectId(), host: this });
108+
try {
109+
return tool.fn(toolArgs, { projectId: await this.getProjectId(), host: this });
110+
} catch (err: unknown) {
111+
return mcpError(err);
112+
}
108113
}
109114

110115
async start(): Promise<void> {
Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { z } from "zod";
22
import { tool } from "../../tool.js";
3-
import { mcpError, toContent } from "../../util.js";
3+
import { toContent } from "../../util.js";
44
import { disableUser } from "../../../gcp/auth.js";
5+
import { NO_PROJECT_ERROR } from "../../errors.js";
56

67
export const disable_auth_user = tool(
78
{
@@ -18,15 +19,11 @@ export const disable_auth_user = tool(
1819
},
1920
},
2021
async ({ uid, disabled }, { projectId }) => {
21-
if (!projectId) return mcpError(`No current project detected.`);
22-
try {
23-
const res = await disableUser(projectId, uid, disabled);
24-
if (res) {
25-
return toContent(`User ${uid} as been ${disabled ? "disabled" : "enabled"}`);
26-
}
27-
return toContent(`Failed to ${disabled ? "disable" : "enable"} user ${uid}`);
28-
} catch (err: unknown) {
29-
return mcpError(err);
22+
if (!projectId) return NO_PROJECT_ERROR;
23+
const res = await disableUser(projectId, uid, disabled);
24+
if (res) {
25+
return toContent(`User ${uid} as been ${disabled ? "disabled" : "enabled"}`);
3026
}
27+
return toContent(`Failed to ${disabled ? "disable" : "enable"} user ${uid}`);
3128
},
3229
);

src/mcp/tools/auth/get_auth_user.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z } from "zod";
22
import { tool } from "../../tool.js";
33
import { mcpError, toContent } from "../../util.js";
44
import { findUser } from "../../../gcp/auth.js";
5+
import { NO_PROJECT_ERROR } from "../../errors.js";
56

67
export const get_auth_user = tool(
78
{
@@ -21,11 +22,7 @@ export const get_auth_user = tool(
2122
if (email === undefined && phoneNumber === undefined && uid === undefined) {
2223
return mcpError(`No user identifier supplied in get_auth_user tool`);
2324
}
24-
if (!projectId) return mcpError(`No current project detected.`);
25-
try {
26-
return toContent(await findUser(projectId, email, phoneNumber, uid));
27-
} catch (err: unknown) {
28-
return mcpError(err);
29-
}
25+
if (!projectId) return NO_PROJECT_ERROR;
26+
return toContent(await findUser(projectId, email, phoneNumber, uid));
3027
},
3128
);

src/mcp/tools/auth/set_auth_claims.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { z } from "zod";
22
import { tool } from "../../tool.js";
3-
import { mcpError, toContent } from "../../util.js";
3+
import { toContent } from "../../util.js";
44
import { setCustomClaim } from "../../../gcp/auth.js";
5+
import { NO_PROJECT_ERROR } from "../../errors.js";
56

67
export const set_auth_claim = tool(
78
{
@@ -27,11 +28,7 @@ export const set_auth_claim = tool(
2728
},
2829
},
2930
async ({ uid, claim, value }, { projectId }) => {
30-
if (!projectId) return mcpError(`No current project detected.`);
31-
try {
32-
return toContent(await setCustomClaim(projectId, uid, { [claim]: value }, { merge: true }));
33-
} catch (err: unknown) {
34-
return mcpError(err);
35-
}
31+
if (!projectId) return NO_PROJECT_ERROR;
32+
return toContent(await setCustomClaim(projectId, uid, { [claim]: value }, { merge: true }));
3633
},
3734
);

src/mcp/tools/firestore/get_documents.ts

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,28 @@ export const get_documents = tool(
3232
if (!projectId) return NO_PROJECT_ERROR;
3333
if (!paths.length) return mcpError("Must supply at least one document path.");
3434

35-
try {
36-
const { documents, missing } = await getDocuments(projectId, paths);
37-
if (missing.length > 0 && documents.length === 0) {
38-
return mcpError(`None of the specified documents were found in project '${projectId}'`);
39-
}
35+
const { documents, missing } = await getDocuments(projectId, paths);
36+
if (missing.length > 0 && documents.length === 0) {
37+
return mcpError(`None of the specified documents were found in project '${projectId}'`);
38+
}
4039

41-
const docs = documents.map(firestoreDocumentToJson);
40+
const docs = documents.map(firestoreDocumentToJson);
4241

43-
if (documents.length === 1 && missing.length === 0) {
44-
// return a single document as YAML if that's all we have/need
45-
return toContent(docs[0]);
46-
}
47-
const docsContent = toContent(docs);
48-
if (missing.length) {
49-
docsContent.content = [
50-
{ type: "text", text: "Retrieved documents:\n\n" },
51-
...docsContent.content,
52-
{
53-
type: "text",
54-
text: `The following documents do not exist: ${missing.join(", ")}`,
55-
},
56-
];
57-
}
58-
return docsContent;
59-
} catch (e) {
60-
return mcpError(e);
42+
if (documents.length === 1 && missing.length === 0) {
43+
// return a single document as YAML if that's all we have/need
44+
return toContent(docs[0]);
45+
}
46+
const docsContent = toContent(docs);
47+
if (missing.length) {
48+
docsContent.content = [
49+
{ type: "text", text: "Retrieved documents:\n\n" },
50+
...docsContent.content,
51+
{
52+
type: "text",
53+
text: `The following documents do not exist: ${missing.join(", ")}`,
54+
},
55+
];
6156
}
57+
return docsContent;
6258
},
6359
);

src/mcp/tools/firestore/get_firestore_rules.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,10 @@ export const get_firestore_rules = tool(
1919
},
2020
async (_, { projectId }) => {
2121
if (!projectId) return NO_PROJECT_ERROR;
22-
try {
23-
const rulesetName = await getLatestRulesetName(projectId, "cloud.firestore");
24-
if (!rulesetName)
25-
return mcpError(`No active Firestore rules were found in project '${projectId}'`);
26-
const rules = await getRulesetContent(rulesetName);
27-
return toContent(rules[0].content);
28-
} catch (e) {
29-
return mcpError(e);
30-
}
22+
const rulesetName = await getLatestRulesetName(projectId, "cloud.firestore");
23+
if (!rulesetName)
24+
return mcpError(`No active Firestore rules were found in project '${projectId}'`);
25+
const rules = await getRulesetContent(rulesetName);
26+
return toContent(rules[0].content);
3127
},
3228
);

src/mcp/tools/firestore/list_collections.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { z } from "zod";
22
import { tool } from "../../tool.js";
3-
import { mcpError, toContent } from "../../util.js";
3+
import { toContent } from "../../util.js";
44
import { listCollectionIds } from "../../../gcp/firestore.js";
55
import { NO_PROJECT_ERROR } from "../../errors.js";
66

@@ -30,10 +30,6 @@ export const list_collections = tool(
3030
async (_, { projectId }) => {
3131
// database ??= "(default)";
3232
if (!projectId) return NO_PROJECT_ERROR;
33-
try {
34-
return toContent(await listCollectionIds(projectId));
35-
} catch (e) {
36-
return mcpError(e);
37-
}
33+
return toContent(await listCollectionIds(projectId));
3834
},
3935
);

src/mcp/tools/project/get_sdk_config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z } from "zod";
22
import { tool } from "../../tool.js";
33
import { mcpError, toContent } from "../../util.js";
44
import { AppPlatform, getAppConfig, listFirebaseApps } from "../../../management/apps.js";
5+
import { NO_PROJECT_ERROR } from "../../errors.js";
56

67
export const get_sdk_config = tool(
78
{
@@ -24,7 +25,7 @@ export const get_sdk_config = tool(
2425
},
2526
},
2627
async ({ platform: inputPlatform, app_id: appId }, { projectId }) => {
27-
if (!projectId) return mcpError("No current project detected.");
28+
if (!projectId) return NO_PROJECT_ERROR;
2829
let platform = inputPlatform?.toUpperCase() as AppPlatform;
2930
if (!platform && !appId)
3031
return mcpError(

src/mcp/tools/project/list_apps.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { z } from "zod";
22
import { tool } from "../../tool.js";
3-
import { mcpError, toContent } from "../../util.js";
3+
import { toContent } from "../../util.js";
44
import { AppPlatform, listFirebaseApps } from "../../../management/apps.js";
5+
import { NO_PROJECT_ERROR } from "../../errors.js";
56

67
export const list_apps = tool(
78
{
@@ -22,7 +23,7 @@ export const list_apps = tool(
2223
},
2324
},
2425
async ({ platform }, { projectId }) => {
25-
if (!projectId) return mcpError("No current project detected.");
26+
if (!projectId) return NO_PROJECT_ERROR;
2627
const apps = await listFirebaseApps(
2728
projectId,
2829
(platform?.toUpperCase() as AppPlatform) ?? AppPlatform.ANY,

0 commit comments

Comments
 (0)