Skip to content

Commit ad3051f

Browse files
refactor(dataconnect): merge dataconnect_execute tools (#9046)
* remove an unecessary includeDebugDetails * Update types.ts * refactor(dataconnect): merge execute tools Merges four dataconnect execute tools (`execute_graphql`, `execute_graphql_read`, `execute_query`, and `execute_mutation`) into a single `dataconnect_execute` tool. The new tool provides a more versatile interface by accepting either a `query` or an `operationName`, and includes a `read_only` flag to control whether the operation can write data. This change simplifies the toolset while preserving all existing functionality. * Update execute.ts * m * fix * m * remove execute_operation * update description * descriptions * changelog --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent cd1e53f commit ad3051f

File tree

9 files changed

+93
-294
lines changed

9 files changed

+93
-294
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Support auth token JSON in `dataconnect_execute` MPC tool. (#9046)

src/dataconnect/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ export interface ExecuteGraphqlRequest {
224224
query: string;
225225
operationName?: string;
226226
variables?: { [key: string]: string };
227-
extensions?: { impersonate?: Impersonation; includeDebugDetails?: boolean };
227+
extensions?: { impersonate?: Impersonation };
228228
}
229229

230230
export interface GraphqlResponse {

src/mcp/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ export class FirebaseMcpServer {
207207
const emulatorInfo = emulators[emulatorType];
208208
if (!emulatorInfo) {
209209
throw Error(
210-
"No Firestore Emulator found running. Make sure your project firebase.json file includes firestore and then rerun emulator using `firebase emulators:start` from your project directory.",
210+
`No ${emulatorType} Emulator found running. Make sure your project firebase.json file includes ${emulatorType} and then rerun emulator using \`firebase emulators:start\` from your project directory.`,
211211
);
212212
}
213213

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { z } from "zod";
2+
3+
import { tool } from "../../tool";
4+
import * as dataplane from "../../../dataconnect/dataplaneClient";
5+
import { pickService } from "../../../dataconnect/load";
6+
import { graphqlResponseToToolResponse, parseVariables } from "../../util/dataconnect/converter";
7+
import { getDataConnectEmulatorClient } from "../../util/dataconnect/emulator";
8+
import { Client } from "../../../apiv2";
9+
10+
export const execute = tool(
11+
{
12+
name: "execute",
13+
description: "Executes a GraphQL operation against a Data Connect service or its emulator.",
14+
inputSchema: z.object({
15+
query: z.string().describe(`A Firebase Data Connect GraphQL query or mutation to execute.
16+
You can use the \`dataconnect_generate_operation\` tool to generate a query.
17+
Example Data Connect schema and example queries can be found in files ending in \`.graphql\` or \`.gql\`.
18+
`),
19+
service_id: z.string().optional()
20+
.describe(`Data Connect Service ID to dis-ambulate if there are multiple.
21+
It's only necessary if there are multiple dataconnect sources in \`firebase.json\`.
22+
You can find candidate service_id in \`dataconnect.yaml\`
23+
`),
24+
variables_json: z
25+
.string()
26+
.optional()
27+
.describe(
28+
"GraphQL variables to pass into the query. MUST be a valid stringified JSON object.",
29+
),
30+
auth_token_json: z
31+
.string()
32+
.optional()
33+
.describe(
34+
"Firebase Auth Token JWT to use in this query. MUST be a valid stringified JSON object." +
35+
'Importantly, when executing queries with `@auth(level: USER)` or `auth.uid`, a valid Firebase Auth Token JWT with "sub" field is required. ' +
36+
'"auth.uid" expression in the query evaluates to the value of "sub" field in Firebase Auth token.',
37+
),
38+
use_emulator: z
39+
.boolean()
40+
.default(false)
41+
.describe(
42+
"If true, target the DataConnect emulator. Run `firebase emulators:start` to start it",
43+
),
44+
}),
45+
annotations: {
46+
title: "Execute Firebase Data Connect Query",
47+
},
48+
_meta: {
49+
requiresProject: true,
50+
requiresAuth: true,
51+
},
52+
},
53+
async (
54+
{
55+
query,
56+
service_id,
57+
variables_json: unparsedVariables,
58+
use_emulator,
59+
auth_token_json: unparsedAuthToken,
60+
},
61+
{ projectId, config, host },
62+
) => {
63+
const serviceInfo = await pickService(projectId, config, service_id || undefined);
64+
let apiClient: Client;
65+
if (use_emulator) {
66+
apiClient = await getDataConnectEmulatorClient(host);
67+
} else {
68+
apiClient = dataplane.dataconnectDataplaneClient();
69+
}
70+
let executeGraphQL = dataplane.executeGraphQL;
71+
if (query.startsWith("query")) {
72+
executeGraphQL = dataplane.executeGraphQLRead;
73+
}
74+
const response = await executeGraphQL(apiClient, serviceInfo.serviceName, {
75+
name: "",
76+
query,
77+
variables: parseVariables(unparsedVariables),
78+
extensions: {
79+
impersonate: unparsedAuthToken
80+
? {
81+
authClaims: parseVariables(unparsedAuthToken),
82+
}
83+
: undefined,
84+
},
85+
});
86+
return graphqlResponseToToolResponse(response.body);
87+
},
88+
);

src/mcp/tools/dataconnect/execute_graphql.ts

Lines changed: 0 additions & 60 deletions
This file was deleted.

src/mcp/tools/dataconnect/execute_graphql_read.ts

Lines changed: 0 additions & 60 deletions
This file was deleted.

src/mcp/tools/dataconnect/execute_mutation.ts

Lines changed: 0 additions & 82 deletions
This file was deleted.

src/mcp/tools/dataconnect/execute_query.ts

Lines changed: 0 additions & 82 deletions
This file was deleted.

0 commit comments

Comments
 (0)