firebase-tools 14.2.0 → 14.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bin/cli.js +131 -0
- package/lib/bin/firebase.js +7 -123
- package/lib/bin/mcp.js +38 -0
- package/lib/commands/index.js +3 -0
- package/lib/commands/mcp.js +11 -0
- package/lib/dataconnect/build.js +1 -9
- package/lib/emulator/commandUtils.js +8 -6
- package/lib/emulator/downloadableEmulators.js +9 -9
- package/lib/emulator/env.js +27 -1
- package/lib/emulator/functionsEmulator.js +3 -4
- package/lib/emulator/hub.js +2 -1
- package/lib/emulator/ui.js +2 -7
- package/lib/experiments.js +3 -4
- package/lib/frameworks/index.js +4 -1
- package/lib/gcp/auth.js +56 -1
- package/lib/gcp/firestore.js +12 -1
- package/lib/hosting/api.js +4 -0
- package/lib/init/features/dataconnect/sdk.js +9 -7
- package/lib/init/features/genkit/index.js +59 -55
- package/lib/logger.js +11 -2
- package/lib/mcp/errors.js +15 -0
- package/lib/mcp/index.js +109 -0
- package/lib/mcp/tool.js +11 -0
- package/lib/mcp/tools/auth/disable_auth_user.js +30 -0
- package/lib/mcp/tools/auth/get_auth_user.js +29 -0
- package/lib/mcp/tools/auth/index.js +7 -0
- package/lib/mcp/tools/auth/set_auth_claims.js +34 -0
- package/lib/mcp/tools/core/get_firebase_directory.js +20 -0
- package/lib/mcp/tools/core/index.js +6 -0
- package/lib/mcp/tools/core/set_firebase_directory.js +33 -0
- package/lib/mcp/tools/dataconnect/index.js +5 -0
- package/lib/mcp/tools/dataconnect/list_dataconnect_services.js +23 -0
- package/lib/mcp/tools/firestore/converter.js +57 -0
- package/lib/mcp/tools/firestore/get_documents.js +48 -0
- package/lib/mcp/tools/firestore/get_firestore_rules.js +26 -0
- package/lib/mcp/tools/firestore/index.js +7 -0
- package/lib/mcp/tools/firestore/list_collections.js +30 -0
- package/lib/mcp/tools/index.js +14 -0
- package/lib/mcp/tools/project/get_project.js +22 -0
- package/lib/mcp/tools/project/get_sdk_config.js +38 -0
- package/lib/mcp/tools/project/index.js +7 -0
- package/lib/mcp/tools/project/list_apps.js +29 -0
- package/lib/mcp/types.js +4 -0
- package/lib/mcp/util.js +52 -0
- package/package.json +5 -2
- package/templates/init/dataconnect/connector.yaml +3 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_documents = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const firestore_js_1 = require("../../../gcp/firestore.js");
|
|
8
|
+
const converter_js_1 = require("./converter.js");
|
|
9
|
+
exports.get_documents = (0, tool_js_1.tool)({
|
|
10
|
+
name: "get_documents",
|
|
11
|
+
description: "Retrieves one or more Firestore documents from a database in the current project by full document paths. Use this if you know the exact path of a document.",
|
|
12
|
+
inputSchema: zod_1.z.object({
|
|
13
|
+
paths: zod_1.z
|
|
14
|
+
.array(zod_1.z.string())
|
|
15
|
+
.describe("One or more document paths (e.g. `collectionName/documentId` or `parentCollection/parentDocument/collectionName/documentId`)"),
|
|
16
|
+
}),
|
|
17
|
+
annotations: {
|
|
18
|
+
title: "Get Firestore documents",
|
|
19
|
+
readOnlyHint: true,
|
|
20
|
+
},
|
|
21
|
+
_meta: {
|
|
22
|
+
requiresAuth: true,
|
|
23
|
+
requiresProject: true,
|
|
24
|
+
},
|
|
25
|
+
}, async ({ paths }, { projectId }) => {
|
|
26
|
+
if (!paths.length)
|
|
27
|
+
return (0, util_js_1.mcpError)("Must supply at least one document path.");
|
|
28
|
+
const { documents, missing } = await (0, firestore_js_1.getDocuments)(projectId, paths);
|
|
29
|
+
if (missing.length > 0 && documents.length === 0) {
|
|
30
|
+
return (0, util_js_1.mcpError)(`None of the specified documents were found in project '${projectId}'`);
|
|
31
|
+
}
|
|
32
|
+
const docs = documents.map(converter_js_1.firestoreDocumentToJson);
|
|
33
|
+
if (documents.length === 1 && missing.length === 0) {
|
|
34
|
+
return (0, util_js_1.toContent)(docs[0]);
|
|
35
|
+
}
|
|
36
|
+
const docsContent = (0, util_js_1.toContent)(docs);
|
|
37
|
+
if (missing.length) {
|
|
38
|
+
docsContent.content = [
|
|
39
|
+
{ type: "text", text: "Retrieved documents:\n\n" },
|
|
40
|
+
...docsContent.content,
|
|
41
|
+
{
|
|
42
|
+
type: "text",
|
|
43
|
+
text: `The following documents do not exist: ${missing.join(", ")}`,
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
return docsContent;
|
|
48
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_firestore_rules = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const rules_1 = require("../../../gcp/rules");
|
|
8
|
+
exports.get_firestore_rules = (0, tool_js_1.tool)({
|
|
9
|
+
name: "get_firestore_rules",
|
|
10
|
+
description: "Retrieves the active Firestore security rules for the current project.",
|
|
11
|
+
inputSchema: zod_1.z.object({}),
|
|
12
|
+
annotations: {
|
|
13
|
+
title: "Get Current Firestore Rules",
|
|
14
|
+
readOnlyHint: true,
|
|
15
|
+
},
|
|
16
|
+
_meta: {
|
|
17
|
+
requiresProject: true,
|
|
18
|
+
requiresAuth: true,
|
|
19
|
+
},
|
|
20
|
+
}, async (_, { projectId }) => {
|
|
21
|
+
const rulesetName = await (0, rules_1.getLatestRulesetName)(projectId, "cloud.firestore");
|
|
22
|
+
if (!rulesetName)
|
|
23
|
+
return (0, util_js_1.mcpError)(`No active Firestore rules were found in project '${projectId}'`);
|
|
24
|
+
const rules = await (0, rules_1.getRulesetContent)(rulesetName);
|
|
25
|
+
return (0, util_js_1.toContent)(rules[0].content);
|
|
26
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.firestoreTools = void 0;
|
|
4
|
+
const get_documents_1 = require("./get_documents");
|
|
5
|
+
const get_firestore_rules_1 = require("./get_firestore_rules");
|
|
6
|
+
const list_collections_1 = require("./list_collections");
|
|
7
|
+
exports.firestoreTools = [list_collections_1.list_collections, get_documents_1.get_documents, get_firestore_rules_1.get_firestore_rules];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.list_collections = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const firestore_js_1 = require("../../../gcp/firestore.js");
|
|
8
|
+
const errors_js_1 = require("../../errors.js");
|
|
9
|
+
exports.list_collections = (0, tool_js_1.tool)({
|
|
10
|
+
name: "list_collections",
|
|
11
|
+
description: "Retrieves a list of collections from a Firestore database in the current project.",
|
|
12
|
+
inputSchema: zod_1.z.object({
|
|
13
|
+
document_path: zod_1.z
|
|
14
|
+
.string()
|
|
15
|
+
.nullish()
|
|
16
|
+
.describe("a parent document to list subcollections under. only needed for subcollections, omit to list top-level collections"),
|
|
17
|
+
}),
|
|
18
|
+
annotations: {
|
|
19
|
+
title: "List Firestore collections",
|
|
20
|
+
readOnlyHint: true,
|
|
21
|
+
},
|
|
22
|
+
_meta: {
|
|
23
|
+
requiresAuth: true,
|
|
24
|
+
requiresProject: true,
|
|
25
|
+
},
|
|
26
|
+
}, async (_, { projectId }) => {
|
|
27
|
+
if (!projectId)
|
|
28
|
+
return errors_js_1.NO_PROJECT_ERROR;
|
|
29
|
+
return (0, util_js_1.toContent)(await (0, firestore_js_1.listCollectionIds)(projectId));
|
|
30
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tools = void 0;
|
|
4
|
+
const index_js_1 = require("./auth/index.js");
|
|
5
|
+
const index_js_2 = require("./dataconnect/index.js");
|
|
6
|
+
const index_js_3 = require("./firestore/index.js");
|
|
7
|
+
const index_js_4 = require("./project/index.js");
|
|
8
|
+
exports.tools = {
|
|
9
|
+
project: index_js_4.projectTools,
|
|
10
|
+
firestore: index_js_3.firestoreTools,
|
|
11
|
+
auth: index_js_1.authTools,
|
|
12
|
+
dataconnect: index_js_2.dataconnectTools,
|
|
13
|
+
storage: [],
|
|
14
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_project = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const projects_js_1 = require("../../../management/projects.js");
|
|
7
|
+
const util_js_1 = require("../../util.js");
|
|
8
|
+
exports.get_project = (0, tool_js_1.tool)({
|
|
9
|
+
name: "get_project",
|
|
10
|
+
description: "Retrieves information about the currently active Firebase project.",
|
|
11
|
+
inputSchema: zod_1.z.object({}),
|
|
12
|
+
annotations: {
|
|
13
|
+
title: "Get Current Firebase Project",
|
|
14
|
+
readOnlyHint: true,
|
|
15
|
+
},
|
|
16
|
+
_meta: {
|
|
17
|
+
requiresAuth: true,
|
|
18
|
+
requiresProject: true,
|
|
19
|
+
},
|
|
20
|
+
}, async (_, { projectId }) => {
|
|
21
|
+
return (0, util_js_1.toContent)(await (0, projects_js_1.getProject)(projectId));
|
|
22
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_sdk_config = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const apps_js_1 = require("../../../management/apps.js");
|
|
8
|
+
exports.get_sdk_config = (0, tool_js_1.tool)({
|
|
9
|
+
name: "get_sdk_config",
|
|
10
|
+
description: "Retrieves the Firebase SDK configuration information for the specified platform. You must specify either a platform or an app_id.",
|
|
11
|
+
inputSchema: zod_1.z.object({
|
|
12
|
+
platform: zod_1.z
|
|
13
|
+
.enum(["ios", "android", "web"])
|
|
14
|
+
.nullish()
|
|
15
|
+
.describe("the platform for which you want config"),
|
|
16
|
+
app_id: zod_1.z.string().nullish().describe("the specific app id to fetch"),
|
|
17
|
+
}),
|
|
18
|
+
annotations: {
|
|
19
|
+
title: "Get Firebase SDK Config",
|
|
20
|
+
readOnlyHint: true,
|
|
21
|
+
},
|
|
22
|
+
_meta: {
|
|
23
|
+
requiresProject: true,
|
|
24
|
+
requiresAuth: true,
|
|
25
|
+
},
|
|
26
|
+
}, async ({ platform: inputPlatform, app_id: appId }, { projectId }) => {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
let platform = inputPlatform === null || inputPlatform === void 0 ? void 0 : inputPlatform.toUpperCase();
|
|
29
|
+
if (!platform && !appId)
|
|
30
|
+
return (0, util_js_1.mcpError)("Must specify one of 'web', 'ios', or 'android' for platform or an app_id for get_sdk_config tool.");
|
|
31
|
+
const apps = await (0, apps_js_1.listFirebaseApps)(projectId, platform !== null && platform !== void 0 ? platform : apps_js_1.AppPlatform.ANY);
|
|
32
|
+
platform = platform || ((_a = apps.find((app) => app.appId === appId)) === null || _a === void 0 ? void 0 : _a.platform);
|
|
33
|
+
appId = appId || ((_b = apps.find((app) => app.platform === platform)) === null || _b === void 0 ? void 0 : _b.appId);
|
|
34
|
+
if (!appId)
|
|
35
|
+
return (0, util_js_1.mcpError)(`Could not find an app for platform '${inputPlatform}' in project '${projectId}'`);
|
|
36
|
+
const sdkConfig = await (0, apps_js_1.getAppConfig)(appId, platform);
|
|
37
|
+
return (0, util_js_1.toContent)(sdkConfig, { format: "json" });
|
|
38
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.projectTools = void 0;
|
|
4
|
+
const get_project_js_1 = require("./get_project.js");
|
|
5
|
+
const get_sdk_config_js_1 = require("./get_sdk_config.js");
|
|
6
|
+
const list_apps_js_1 = require("./list_apps.js");
|
|
7
|
+
exports.projectTools = [get_project_js_1.get_project, list_apps_js_1.list_apps, get_sdk_config_js_1.get_sdk_config];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.list_apps = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const apps_js_1 = require("../../../management/apps.js");
|
|
8
|
+
exports.list_apps = (0, tool_js_1.tool)({
|
|
9
|
+
name: "list_apps",
|
|
10
|
+
description: "Retrieves apps registered in the current Firebase project.",
|
|
11
|
+
inputSchema: zod_1.z.object({
|
|
12
|
+
platform: zod_1.z
|
|
13
|
+
.enum(["ios", "android", "web"])
|
|
14
|
+
.nullish()
|
|
15
|
+
.describe("the specific platform to list (omit to list all platforms)"),
|
|
16
|
+
}),
|
|
17
|
+
annotations: {
|
|
18
|
+
title: "List Firebase Apps",
|
|
19
|
+
readOnlyHint: true,
|
|
20
|
+
},
|
|
21
|
+
_meta: {
|
|
22
|
+
requiresProject: true,
|
|
23
|
+
requiresAuth: true,
|
|
24
|
+
},
|
|
25
|
+
}, async ({ platform }, { projectId }) => {
|
|
26
|
+
var _a;
|
|
27
|
+
const apps = await (0, apps_js_1.listFirebaseApps)(projectId, (_a = platform === null || platform === void 0 ? void 0 : platform.toUpperCase()) !== null && _a !== void 0 ? _a : apps_js_1.AppPlatform.ANY);
|
|
28
|
+
return (0, util_js_1.toContent)(apps);
|
|
29
|
+
});
|
package/lib/mcp/types.js
ADDED
package/lib/mcp/util.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.commandExistsSync = exports.mcpError = exports.toContent = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const js_yaml_1 = require("js-yaml");
|
|
6
|
+
const os_1 = require("os");
|
|
7
|
+
function toContent(data, options) {
|
|
8
|
+
if (typeof data === "string")
|
|
9
|
+
return { content: [{ type: "text", text: data }] };
|
|
10
|
+
let text = "";
|
|
11
|
+
const format = (options === null || options === void 0 ? void 0 : options.format) || "yaml";
|
|
12
|
+
switch (format) {
|
|
13
|
+
case "json":
|
|
14
|
+
text = JSON.stringify(data);
|
|
15
|
+
break;
|
|
16
|
+
case "yaml":
|
|
17
|
+
text = (0, js_yaml_1.dump)(data);
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
content: [{ type: "text", text }],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
exports.toContent = toContent;
|
|
25
|
+
function mcpError(message, code) {
|
|
26
|
+
let errorMessage = "unknown error";
|
|
27
|
+
if (message instanceof Error) {
|
|
28
|
+
errorMessage = message.message;
|
|
29
|
+
}
|
|
30
|
+
if (typeof message === "string") {
|
|
31
|
+
errorMessage = message;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
isError: true,
|
|
35
|
+
content: [{ type: "text", text: `Error: ${code ? `${code}: ` : ""}${errorMessage}` }],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
exports.mcpError = mcpError;
|
|
39
|
+
function commandExistsSync(command) {
|
|
40
|
+
try {
|
|
41
|
+
const isWindows = (0, os_1.platform)() === "win32";
|
|
42
|
+
const commandToCheck = isWindows
|
|
43
|
+
? `where "${command}" > nul 2> nul`
|
|
44
|
+
: `which "${command}" > /dev/null 2> /dev/null`;
|
|
45
|
+
(0, child_process_1.execSync)(commandToCheck);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.commandExistsSync = commandExistsSync;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firebase-tools",
|
|
3
|
-
"version": "14.2.
|
|
3
|
+
"version": "14.2.2",
|
|
4
4
|
"description": "Command-Line Interface for Firebase",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"@electric-sql/pglite": "^0.2.16",
|
|
64
64
|
"@google-cloud/cloud-sql-connector": "^1.3.3",
|
|
65
65
|
"@google-cloud/pubsub": "^4.5.0",
|
|
66
|
+
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
66
67
|
"abort-controller": "^3.0.0",
|
|
67
68
|
"ajv": "^8.17.1",
|
|
68
69
|
"ajv-formats": "3.0.1",
|
|
@@ -127,7 +128,9 @@
|
|
|
127
128
|
"winston": "^3.0.0",
|
|
128
129
|
"winston-transport": "^4.4.0",
|
|
129
130
|
"ws": "^7.5.10",
|
|
130
|
-
"yaml": "^2.4.1"
|
|
131
|
+
"yaml": "^2.4.1",
|
|
132
|
+
"zod": "^3.24.3",
|
|
133
|
+
"zod-to-json-schema": "^3.24.5"
|
|
131
134
|
},
|
|
132
135
|
"overrides": {
|
|
133
136
|
"@angular-devkit/core": {
|
|
@@ -12,3 +12,6 @@ connectorId: __connectorId__
|
|
|
12
12
|
# kotlinSdk:
|
|
13
13
|
# outputDir: <Path where you want the generated SDK to be written to, relative to this file>
|
|
14
14
|
# package: connectors.default
|
|
15
|
+
# dartSdk:
|
|
16
|
+
# outputDir: <Path where you want the generated SDK to be written to, relative to this file>
|
|
17
|
+
# package: default_connector
|