firebase-tools 15.5.1 → 15.7.0
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/api.js +3 -1
- package/lib/apiv2.js +6 -6
- package/lib/bin/mcp.js +1 -1
- package/lib/commands/deploy.js +3 -0
- package/lib/commands/init.js +5 -0
- package/lib/config.js +1 -0
- package/lib/dataconnect/client.js +2 -2
- package/lib/dataconnect/prompts.js +14 -0
- package/lib/deploy/auth/deploy.js +63 -0
- package/lib/deploy/auth/index.js +9 -0
- package/lib/deploy/auth/prepare.js +26 -0
- package/lib/deploy/auth/release.js +5 -0
- package/lib/deploy/dataconnect/release.js +11 -0
- package/lib/deploy/functions/backend.js +10 -0
- package/lib/deploy/functions/build.js +2 -2
- package/lib/deploy/functions/checkIam.js +3 -2
- package/lib/deploy/functions/deploy.js +4 -2
- package/lib/deploy/functions/prepare.js +5 -2
- package/lib/deploy/functions/prepareFunctionsUpload.js +7 -5
- package/lib/deploy/functions/release/fabricator.js +96 -15
- package/lib/deploy/functions/release/index.js +2 -1
- package/lib/deploy/functions/runtimes/dart.js +42 -0
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +4 -1
- package/lib/deploy/functions/runtimes/index.js +9 -1
- package/lib/deploy/functions/runtimes/supported/types.js +6 -0
- package/lib/deploy/index.js +2 -0
- package/lib/emulator/auth/index.js +23 -17
- package/lib/emulator/auth/operations.js +9 -1
- package/lib/emulator/downloadableEmulatorInfo.json +31 -31
- package/lib/emulator/hubExport.js +15 -1
- package/lib/gcp/cloudbilling.js +6 -3
- package/lib/gcp/runv2.js +75 -3
- package/lib/gemini/fdcExperience.js +0 -11
- package/lib/init/features/auth.js +72 -0
- package/lib/init/features/dataconnect/resolver.js +17 -3
- package/lib/init/features/functions/index.js +22 -14
- package/lib/init/features/functions/javascript.js +18 -3
- package/lib/init/features/functions/typescript.js +20 -3
- package/lib/init/features/functions/utils.js +10 -0
- package/lib/init/features/genkit/index.js +3 -2
- package/lib/init/features/index.js +6 -2
- package/lib/init/index.js +11 -1
- package/lib/management/provisioning/provision.js +3 -0
- package/lib/management/provisioning/types.js +7 -0
- package/lib/mcp/onemcp/index.js +8 -0
- package/lib/mcp/onemcp/onemcp_server.js +77 -0
- package/lib/mcp/prompts/index.js +1 -0
- package/lib/mcp/resources/guides/init_auth.js +19 -2
- package/lib/mcp/tools/apptesting/tests.js +6 -4
- package/lib/mcp/tools/core/init.js +31 -0
- package/lib/mcp/tools/index.js +52 -32
- package/lib/mcp/types.js +1 -0
- package/lib/mcp/util/availability.js +2 -1
- package/lib/mcp/util.js +2 -0
- package/lib/tsconfig.publish.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/schema/firebase-config.json +41 -0
- package/templates/init/apptesting/smoke_test.yaml +1 -1
- package/templates/init/dataconnect/secondary_schema.gql +8 -0
- package/templates/init/functions/javascript/index-ongraphrequest.js +36 -0
- package/templates/init/functions/javascript/package-ongraphrequest.lint.json +28 -0
- package/templates/init/functions/javascript/package-ongraphrequest.nolint.json +25 -0
- package/templates/init/functions/python/requirements.txt +1 -1
- package/templates/init/functions/typescript/index-ongraphrequest.ts +44 -0
- package/templates/init/functions/typescript/package-ongraphrequest.lint.json +33 -0
- package/templates/init/functions/typescript/package-ongraphrequest.nolint.json +27 -0
- package/lib/mcp/util.test.js +0 -468
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setup = setup;
|
|
4
4
|
const npm_dependencies_1 = require("./npm-dependencies");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
5
6
|
const prompt_1 = require("../../../prompt");
|
|
6
7
|
const projectConfig_1 = require("../../../functions/projectConfig");
|
|
7
8
|
const templates_1 = require("../../../templates");
|
|
8
9
|
const supported = require("../../../deploy/functions/runtimes/supported");
|
|
9
10
|
const INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/index.js");
|
|
11
|
+
const GRAPH_INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/index-ongraphrequest.js");
|
|
10
12
|
const PACKAGE_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package.lint.json");
|
|
11
13
|
const PACKAGE_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package.nolint.json");
|
|
14
|
+
const PACKAGE_GRAPH_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package-ongraphrequest.lint.json");
|
|
15
|
+
const PACKAGE_GRAPH_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package-ongraphrequest.nolint.json");
|
|
12
16
|
const ESLINT_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/_eslintrc");
|
|
13
17
|
const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/_gitignore");
|
|
14
18
|
async function setup(setup, config) {
|
|
@@ -18,13 +22,24 @@ async function setup(setup, config) {
|
|
|
18
22
|
if (setup.functions.lint) {
|
|
19
23
|
const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, setup.functions.codebase);
|
|
20
24
|
cbconfig.predeploy = ['npm --prefix "$RESOURCE_DIR" run lint'];
|
|
21
|
-
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
22
25
|
await config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
|
|
23
26
|
}
|
|
27
|
+
let packageTemplate = PACKAGE_LINTING_TEMPLATE;
|
|
28
|
+
if (setup.featureInfo?.dataconnectResolver) {
|
|
29
|
+
packageTemplate = setup.functions.lint
|
|
30
|
+
? PACKAGE_GRAPH_LINTING_TEMPLATE
|
|
31
|
+
: PACKAGE_GRAPH_NO_LINTING_TEMPLATE;
|
|
32
|
+
}
|
|
33
|
+
else if (!setup.functions.lint) {
|
|
34
|
+
packageTemplate = PACKAGE_NO_LINTING_TEMPLATE;
|
|
35
|
+
}
|
|
36
|
+
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, packageTemplate.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
37
|
+
if (setup.featureInfo?.dataconnectResolver) {
|
|
38
|
+
await config.askWriteProjectFile(`${setup.functions.source}/index.js`, (0, utils_1.templateWithSubbedResolverId)(setup.featureInfo.dataconnectResolver.id, GRAPH_INDEX_TEMPLATE));
|
|
39
|
+
}
|
|
24
40
|
else {
|
|
25
|
-
await config.askWriteProjectFile(`${setup.functions.source}/
|
|
41
|
+
await config.askWriteProjectFile(`${setup.functions.source}/index.js`, INDEX_TEMPLATE);
|
|
26
42
|
}
|
|
27
|
-
await config.askWriteProjectFile(`${setup.functions.source}/index.js`, INDEX_TEMPLATE);
|
|
28
43
|
await config.askWriteProjectFile(`${setup.functions.source}/.gitignore`, GITIGNORE_TEMPLATE);
|
|
29
44
|
await (0, npm_dependencies_1.askInstallDependencies)(setup.functions, config);
|
|
30
45
|
}
|
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setup = setup;
|
|
4
4
|
const npm_dependencies_1 = require("./npm-dependencies");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
5
6
|
const prompt_1 = require("../../../prompt");
|
|
6
7
|
const projectConfig_1 = require("../../../functions/projectConfig");
|
|
7
8
|
const templates_1 = require("../../../templates");
|
|
8
9
|
const supported = require("../../../deploy/functions/runtimes/supported");
|
|
9
10
|
const PACKAGE_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package.lint.json");
|
|
10
11
|
const PACKAGE_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package.nolint.json");
|
|
12
|
+
const PACKAGE_GRAPH_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package-ongraphrequest.lint.json");
|
|
13
|
+
const PACKAGE_GRAPH_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package-ongraphrequest.nolint.json");
|
|
11
14
|
const ESLINT_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/_eslintrc");
|
|
12
15
|
const TSCONFIG_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/tsconfig.json");
|
|
13
16
|
const TSCONFIG_DEV_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/tsconfig.dev.json");
|
|
14
17
|
const INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/index.ts");
|
|
18
|
+
const GRAPH_INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/index-ongraphrequest.ts");
|
|
15
19
|
const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/_gitignore");
|
|
16
20
|
async function setup(setup, config) {
|
|
17
21
|
setup.functions.lint =
|
|
@@ -25,16 +29,29 @@ async function setup(setup, config) {
|
|
|
25
29
|
if (setup.functions.lint) {
|
|
26
30
|
cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run lint');
|
|
27
31
|
cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
|
|
28
|
-
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
29
32
|
await config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
|
|
30
33
|
await config.askWriteProjectFile(`${setup.functions.source}/tsconfig.dev.json`, TSCONFIG_DEV_TEMPLATE);
|
|
31
34
|
}
|
|
32
35
|
else {
|
|
33
36
|
cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
|
|
34
|
-
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
35
37
|
}
|
|
38
|
+
let packageTemplate = PACKAGE_LINTING_TEMPLATE;
|
|
39
|
+
if (setup.featureInfo?.dataconnectResolver) {
|
|
40
|
+
packageTemplate = setup.functions.lint
|
|
41
|
+
? PACKAGE_GRAPH_LINTING_TEMPLATE
|
|
42
|
+
: PACKAGE_GRAPH_NO_LINTING_TEMPLATE;
|
|
43
|
+
}
|
|
44
|
+
else if (!setup.functions.lint) {
|
|
45
|
+
packageTemplate = PACKAGE_NO_LINTING_TEMPLATE;
|
|
46
|
+
}
|
|
47
|
+
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, packageTemplate.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
36
48
|
await config.askWriteProjectFile(`${setup.functions.source}/tsconfig.json`, TSCONFIG_TEMPLATE);
|
|
37
|
-
|
|
49
|
+
if (setup.featureInfo?.dataconnectResolver) {
|
|
50
|
+
await config.askWriteProjectFile(`${setup.functions.source}/src/index.ts`, (0, utils_1.templateWithSubbedResolverId)(setup.featureInfo.dataconnectResolver.id, GRAPH_INDEX_TEMPLATE));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
await config.askWriteProjectFile(`${setup.functions.source}/src/index.ts`, INDEX_TEMPLATE);
|
|
54
|
+
}
|
|
38
55
|
await config.askWriteProjectFile(`${setup.functions.source}/.gitignore`, GITIGNORE_TEMPLATE);
|
|
39
56
|
await (0, npm_dependencies_1.askInstallDependencies)(setup.functions, config);
|
|
40
57
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.templateWithSubbedResolverId = templateWithSubbedResolverId;
|
|
4
|
+
function templateWithSubbedResolverId(resolverId, template) {
|
|
5
|
+
let replaced = template;
|
|
6
|
+
const resolverIdWithUnderscores = resolverId.replaceAll("-", "_");
|
|
7
|
+
replaced = replaced.replace("__resolverId__", resolverId);
|
|
8
|
+
replaced = replaced.replace("__resolverIdWithUnderscores__", resolverIdWithUnderscores);
|
|
9
|
+
return replaced;
|
|
10
|
+
}
|
|
@@ -9,7 +9,7 @@ const fs = require("fs");
|
|
|
9
9
|
const path = require("path");
|
|
10
10
|
const semver = require("semver");
|
|
11
11
|
const clc = require("colorette");
|
|
12
|
-
const
|
|
12
|
+
const functions = require("../functions");
|
|
13
13
|
const prompt_1 = require("../../../prompt");
|
|
14
14
|
const spawn_1 = require("../../spawn");
|
|
15
15
|
const projectUtils_1 = require("../../../projectUtils");
|
|
@@ -114,7 +114,8 @@ async function doSetup(initSetup, config, options) {
|
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
116
|
setup.languageOverride = "typescript";
|
|
117
|
-
await
|
|
117
|
+
await functions.askQuestions(setup, config, options);
|
|
118
|
+
await functions.actuate(setup, config);
|
|
118
119
|
delete setup.languageOverride;
|
|
119
120
|
logger_1.logger.info();
|
|
120
121
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.aiLogicActuate = exports.aiLogicAskQuestions = exports.aitools = exports.apptestingAcutate = exports.apptestingAskQuestions = exports.genkit = exports.apphosting = exports.dataconnectResolverActuate = exports.dataconnectResolverAskQuestions = exports.dataconnectSdkActuate = exports.dataconnectSdkAskQuestions = exports.dataconnectActuate = exports.dataconnectAskQuestions = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storageActuate = exports.storageAskQuestions = exports.hostingActuate = exports.hostingAskQuestions = exports.
|
|
3
|
+
exports.authActuate = exports.authAskQuestions = exports.aiLogicActuate = exports.aiLogicAskQuestions = exports.aitools = exports.apptestingAcutate = exports.apptestingAskQuestions = exports.genkit = exports.apphosting = exports.dataconnectResolverActuate = exports.dataconnectResolverAskQuestions = exports.dataconnectSdkActuate = exports.dataconnectSdkAskQuestions = exports.dataconnectActuate = exports.dataconnectAskQuestions = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storageActuate = exports.storageAskQuestions = exports.hostingActuate = exports.hostingAskQuestions = exports.functionsActuate = exports.functionsAskQuestions = exports.firestoreActuate = exports.firestoreAskQuestions = exports.databaseActuate = exports.databaseAskQuestions = exports.account = void 0;
|
|
4
4
|
var account_1 = require("./account");
|
|
5
5
|
Object.defineProperty(exports, "account", { enumerable: true, get: function () { return account_1.doSetup; } });
|
|
6
6
|
var database_1 = require("./database");
|
|
@@ -10,7 +10,8 @@ var firestore_1 = require("./firestore");
|
|
|
10
10
|
Object.defineProperty(exports, "firestoreAskQuestions", { enumerable: true, get: function () { return firestore_1.askQuestions; } });
|
|
11
11
|
Object.defineProperty(exports, "firestoreActuate", { enumerable: true, get: function () { return firestore_1.actuate; } });
|
|
12
12
|
var functions_1 = require("./functions");
|
|
13
|
-
Object.defineProperty(exports, "
|
|
13
|
+
Object.defineProperty(exports, "functionsAskQuestions", { enumerable: true, get: function () { return functions_1.askQuestions; } });
|
|
14
|
+
Object.defineProperty(exports, "functionsActuate", { enumerable: true, get: function () { return functions_1.actuate; } });
|
|
14
15
|
var hosting_1 = require("./hosting");
|
|
15
16
|
Object.defineProperty(exports, "hostingAskQuestions", { enumerable: true, get: function () { return hosting_1.askQuestions; } });
|
|
16
17
|
Object.defineProperty(exports, "hostingActuate", { enumerable: true, get: function () { return hosting_1.actuate; } });
|
|
@@ -48,3 +49,6 @@ Object.defineProperty(exports, "aitools", { enumerable: true, get: function () {
|
|
|
48
49
|
var ailogic_1 = require("./ailogic");
|
|
49
50
|
Object.defineProperty(exports, "aiLogicAskQuestions", { enumerable: true, get: function () { return ailogic_1.askQuestions; } });
|
|
50
51
|
Object.defineProperty(exports, "aiLogicActuate", { enumerable: true, get: function () { return ailogic_1.actuate; } });
|
|
52
|
+
var auth_1 = require("./auth");
|
|
53
|
+
Object.defineProperty(exports, "authAskQuestions", { enumerable: true, get: function () { return auth_1.askQuestions; } });
|
|
54
|
+
Object.defineProperty(exports, "authActuate", { enumerable: true, get: function () { return auth_1.actuate; } });
|
package/lib/init/index.js
CHANGED
|
@@ -35,7 +35,11 @@ const featuresList = [
|
|
|
35
35
|
askQuestions: features.dataconnectResolverAskQuestions,
|
|
36
36
|
actuate: features.dataconnectResolverActuate,
|
|
37
37
|
},
|
|
38
|
-
{
|
|
38
|
+
{
|
|
39
|
+
name: "functions",
|
|
40
|
+
askQuestions: features.functionsAskQuestions,
|
|
41
|
+
actuate: features.functionsActuate,
|
|
42
|
+
},
|
|
39
43
|
{
|
|
40
44
|
name: "hosting",
|
|
41
45
|
askQuestions: features.hostingAskQuestions,
|
|
@@ -64,6 +68,12 @@ const featuresList = [
|
|
|
64
68
|
actuate: features.aiLogicActuate,
|
|
65
69
|
},
|
|
66
70
|
{ name: "aitools", displayName: "AI Tools", doSetup: features.aitools },
|
|
71
|
+
{
|
|
72
|
+
name: "auth",
|
|
73
|
+
displayName: "Authentication",
|
|
74
|
+
askQuestions: features.authAskQuestions,
|
|
75
|
+
actuate: features.authActuate,
|
|
76
|
+
},
|
|
67
77
|
];
|
|
68
78
|
const featureMap = new Map(featuresList.map((feature) => [feature.name, feature]));
|
|
69
79
|
async function init(setup, config, options) {
|
|
@@ -80,6 +80,9 @@ function buildProvisionRequest(options) {
|
|
|
80
80
|
...(options.features?.firebaseAiLogicInput && {
|
|
81
81
|
firebaseAiLogicInput: options.features.firebaseAiLogicInput,
|
|
82
82
|
}),
|
|
83
|
+
...(options.features?.firebaseAuthInput && {
|
|
84
|
+
firebaseAuthInput: options.features.firebaseAuthInput,
|
|
85
|
+
}),
|
|
83
86
|
...platformInput,
|
|
84
87
|
};
|
|
85
88
|
}
|
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProviderMode = void 0;
|
|
4
|
+
var ProviderMode;
|
|
5
|
+
(function (ProviderMode) {
|
|
6
|
+
ProviderMode["PROVIDER_MODE_UNSPECIFIED"] = "PROVIDER_MODE_UNSPECIFIED";
|
|
7
|
+
ProviderMode["PROVIDER_ENABLED"] = "PROVIDER_ENABLED";
|
|
8
|
+
ProviderMode["PROVIDER_DISABLED"] = "PROVIDER_DISABLED";
|
|
9
|
+
})(ProviderMode || (exports.ProviderMode = ProviderMode = {}));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ONEMCP_SERVERS = void 0;
|
|
4
|
+
const api_1 = require("../../api");
|
|
5
|
+
const onemcp_server_1 = require("./onemcp_server");
|
|
6
|
+
exports.ONEMCP_SERVERS = {
|
|
7
|
+
developerknowledge: new onemcp_server_1.OneMcpServer("developerknowledge", (0, api_1.developerKnowledgeOrigin)()),
|
|
8
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OneMcpServer = void 0;
|
|
4
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
5
|
+
const apiv2_1 = require("../../apiv2");
|
|
6
|
+
const error_1 = require("../../error");
|
|
7
|
+
const ensureApiEnabled_1 = require("../../ensureApiEnabled");
|
|
8
|
+
class OneMcpServer {
|
|
9
|
+
constructor(feature, serverUrl) {
|
|
10
|
+
this.feature = feature;
|
|
11
|
+
this.serverUrl = serverUrl;
|
|
12
|
+
this.listClient = new apiv2_1.Client({
|
|
13
|
+
urlPrefix: this.serverUrl,
|
|
14
|
+
auth: false,
|
|
15
|
+
});
|
|
16
|
+
this.callClient = new apiv2_1.Client({
|
|
17
|
+
urlPrefix: this.serverUrl,
|
|
18
|
+
auth: true,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async listTools() {
|
|
22
|
+
try {
|
|
23
|
+
const res = await this.listClient.post("/mcp", {
|
|
24
|
+
method: "tools/list",
|
|
25
|
+
jsonrpc: "2.0",
|
|
26
|
+
id: 1,
|
|
27
|
+
});
|
|
28
|
+
const parsed = types_js_1.ListToolsResultSchema.parse(res.body.result);
|
|
29
|
+
return parsed.tools.map((mcpTool) => ({
|
|
30
|
+
mcp: {
|
|
31
|
+
...mcpTool,
|
|
32
|
+
name: `${this.feature}_${mcpTool.name}`,
|
|
33
|
+
_meta: {
|
|
34
|
+
requiresAuth: true,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
fn: (args, ctx) => this.callTool(mcpTool.name, args, ctx),
|
|
38
|
+
isAvailable: () => Promise.resolve(true),
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw new error_1.FirebaseError("Failed to fetch remote tools for " + this.serverUrl + ": " + JSON.stringify(error));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async callTool(toolName, args, ctx) {
|
|
46
|
+
await (0, ensureApiEnabled_1.ensure)(ctx.projectId, this.serverUrl, this.feature, true);
|
|
47
|
+
try {
|
|
48
|
+
const res = await this.callClient.post("/mcp", {
|
|
49
|
+
method: "tools/call",
|
|
50
|
+
params: {
|
|
51
|
+
name: toolName,
|
|
52
|
+
arguments: args,
|
|
53
|
+
},
|
|
54
|
+
jsonrpc: "2.0",
|
|
55
|
+
id: 1,
|
|
56
|
+
}, ctx.projectId
|
|
57
|
+
? {
|
|
58
|
+
headers: {
|
|
59
|
+
"x-goog-user-project": ctx.projectId,
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
: {});
|
|
63
|
+
return types_js_1.CallToolResultSchema.parse(res.body.result);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error instanceof error_1.FirebaseError) {
|
|
67
|
+
const firebaseError = error;
|
|
68
|
+
const body = firebaseError.context?.body;
|
|
69
|
+
if (body?.result?.isError) {
|
|
70
|
+
return types_js_1.CallToolResultSchema.parse(body.result);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.OneMcpServer = OneMcpServer;
|
package/lib/mcp/prompts/index.js
CHANGED
|
@@ -21,6 +21,7 @@ const prompts = {
|
|
|
21
21
|
apptesting: namespacePrompts(apptesting_1.apptestingPrompts, "apptesting"),
|
|
22
22
|
apphosting: [],
|
|
23
23
|
database: [],
|
|
24
|
+
developerknowledge: [],
|
|
24
25
|
};
|
|
25
26
|
function namespacePrompts(promptsToNamespace, feature) {
|
|
26
27
|
return promptsToNamespace.map((p) => {
|
|
@@ -18,8 +18,25 @@ exports.init_auth = (0, resource_1.resource)({
|
|
|
18
18
|
|
|
19
19
|
**Permission & Setup:**
|
|
20
20
|
- Request developer permission before implementing sign-up and login features
|
|
21
|
-
-
|
|
22
|
-
|
|
21
|
+
- Configure authentication providers in \`firebase.json\`:
|
|
22
|
+
\`\`\`json
|
|
23
|
+
{
|
|
24
|
+
"auth": {
|
|
25
|
+
"providers": {
|
|
26
|
+
"emailPassword": true,
|
|
27
|
+
"googleSignIn": {
|
|
28
|
+
"oAuthBrandDisplayName": "My App",
|
|
29
|
+
"supportEmail": "support@example.com",
|
|
30
|
+
"authorizedRedirectUris": [
|
|
31
|
+
"https://example-website.com",
|
|
32
|
+
"http://localhost:4000"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
\`\`\`
|
|
39
|
+
- Run \`firebase deploy --only auth\` to enable the configured providers
|
|
23
40
|
|
|
24
41
|
**Implementation:**
|
|
25
42
|
- Create sign-up and login pages using Firebase Authentication
|
|
@@ -92,8 +92,10 @@ exports.check_status = (0, tool_1.tool)("apptesting", {
|
|
|
92
92
|
if (getAvailableDevices) {
|
|
93
93
|
devices = await (0, apptesting_1.testEnvironmentCatalog)(projectId || "", "ANDROID");
|
|
94
94
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
const result = {};
|
|
96
|
+
if (devices)
|
|
97
|
+
result.devices = devices;
|
|
98
|
+
if (releaseTest)
|
|
99
|
+
result.releaseTest = releaseTest;
|
|
100
|
+
return (0, util_1.toContent)(result);
|
|
99
101
|
});
|
|
@@ -129,6 +129,27 @@ exports.init = (0, tool_1.tool)("core", {
|
|
|
129
129
|
})
|
|
130
130
|
.optional()
|
|
131
131
|
.describe("Provide this object to initialize Firebase Hosting in this project directory."),
|
|
132
|
+
auth: zod_1.z
|
|
133
|
+
.object({
|
|
134
|
+
providers: zod_1.z.object({
|
|
135
|
+
emailPassword: zod_1.z
|
|
136
|
+
.boolean()
|
|
137
|
+
.optional()
|
|
138
|
+
.describe("Enable Email/Password authentication."),
|
|
139
|
+
anonymous: zod_1.z.boolean().optional().describe("Enable Anonymous authentication."),
|
|
140
|
+
googleSignIn: zod_1.z
|
|
141
|
+
.object({
|
|
142
|
+
oAuthBrandDisplayName: zod_1.z
|
|
143
|
+
.string()
|
|
144
|
+
.describe("The display name for the OAuth brand."),
|
|
145
|
+
supportEmail: zod_1.z.string().describe("The support email for the OAuth brand."),
|
|
146
|
+
})
|
|
147
|
+
.optional()
|
|
148
|
+
.describe("Configure Google Sign-In."),
|
|
149
|
+
}),
|
|
150
|
+
})
|
|
151
|
+
.optional()
|
|
152
|
+
.describe("Provide this object to initialize Firebase Authentication."),
|
|
132
153
|
}),
|
|
133
154
|
}),
|
|
134
155
|
annotations: {
|
|
@@ -202,6 +223,16 @@ exports.init = (0, tool_1.tool)("core", {
|
|
|
202
223
|
spa: features.hosting.single_page_app,
|
|
203
224
|
};
|
|
204
225
|
}
|
|
226
|
+
if (features.auth) {
|
|
227
|
+
featuresList.push("auth");
|
|
228
|
+
featureInfo.auth = {
|
|
229
|
+
providers: {
|
|
230
|
+
anonymous: features.auth.providers.anonymous,
|
|
231
|
+
emailPassword: features.auth.providers.emailPassword,
|
|
232
|
+
googleSignIn: features.auth.providers.googleSignIn,
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
205
236
|
const setup = {
|
|
206
237
|
config: config?.src,
|
|
207
238
|
rcfile: rc?.data,
|
package/lib/mcp/tools/index.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getToolsByFeature = getToolsByFeature;
|
|
4
|
+
exports.getRemoteToolsByFeature = getRemoteToolsByFeature;
|
|
4
5
|
exports.availableTools = availableTools;
|
|
5
6
|
exports.markdownDocsOfTools = markdownDocsOfTools;
|
|
6
|
-
const index_1 = require("
|
|
7
|
-
const index_2 = require("./
|
|
8
|
-
const index_3 = require("./
|
|
9
|
-
const index_4 = require("./
|
|
10
|
-
const index_5 = require("./
|
|
11
|
-
const index_6 = require("./
|
|
12
|
-
const index_7 = require("./
|
|
13
|
-
const index_8 = require("./
|
|
14
|
-
const index_9 = require("./
|
|
15
|
-
const index_10 = require("./
|
|
16
|
-
const index_11 = require("./
|
|
17
|
-
const index_12 = require("./
|
|
7
|
+
const index_1 = require("../onemcp/index");
|
|
8
|
+
const index_2 = require("./apphosting/index");
|
|
9
|
+
const index_3 = require("./apptesting/index");
|
|
10
|
+
const index_4 = require("./auth/index");
|
|
11
|
+
const index_5 = require("./core/index");
|
|
12
|
+
const index_6 = require("./crashlytics/index");
|
|
13
|
+
const index_7 = require("./dataconnect/index");
|
|
14
|
+
const index_8 = require("./firestore/index");
|
|
15
|
+
const index_9 = require("./functions/index");
|
|
16
|
+
const index_10 = require("./messaging/index");
|
|
17
|
+
const index_11 = require("./realtime_database/index");
|
|
18
|
+
const index_12 = require("./remoteconfig/index");
|
|
19
|
+
const index_13 = require("./storage/index");
|
|
18
20
|
function addFeaturePrefix(feature, tools) {
|
|
19
21
|
return tools.map((tool) => ({
|
|
20
22
|
...tool,
|
|
@@ -29,37 +31,55 @@ function addFeaturePrefix(feature, tools) {
|
|
|
29
31
|
}));
|
|
30
32
|
}
|
|
31
33
|
const tools = {
|
|
32
|
-
apphosting: addFeaturePrefix("apphosting",
|
|
33
|
-
apptesting: addFeaturePrefix("apptesting",
|
|
34
|
-
auth: addFeaturePrefix("auth",
|
|
35
|
-
core: addFeaturePrefix("firebase",
|
|
36
|
-
crashlytics: addFeaturePrefix("crashlytics",
|
|
37
|
-
database: addFeaturePrefix("realtimedatabase",
|
|
38
|
-
dataconnect: addFeaturePrefix("dataconnect",
|
|
39
|
-
firestore: addFeaturePrefix("firestore",
|
|
40
|
-
functions: addFeaturePrefix("functions",
|
|
41
|
-
messaging: addFeaturePrefix("messaging",
|
|
42
|
-
remoteconfig: addFeaturePrefix("remoteconfig",
|
|
43
|
-
storage: addFeaturePrefix("storage",
|
|
34
|
+
apphosting: addFeaturePrefix("apphosting", index_2.appHostingTools),
|
|
35
|
+
apptesting: addFeaturePrefix("apptesting", index_3.apptestingTools),
|
|
36
|
+
auth: addFeaturePrefix("auth", index_4.authTools),
|
|
37
|
+
core: addFeaturePrefix("firebase", index_5.coreTools),
|
|
38
|
+
crashlytics: addFeaturePrefix("crashlytics", index_6.crashlyticsTools),
|
|
39
|
+
database: addFeaturePrefix("realtimedatabase", index_11.realtimeDatabaseTools),
|
|
40
|
+
dataconnect: addFeaturePrefix("dataconnect", index_7.dataconnectTools),
|
|
41
|
+
firestore: addFeaturePrefix("firestore", index_8.firestoreTools),
|
|
42
|
+
functions: addFeaturePrefix("functions", index_9.functionsTools),
|
|
43
|
+
messaging: addFeaturePrefix("messaging", index_10.messagingTools),
|
|
44
|
+
remoteconfig: addFeaturePrefix("remoteconfig", index_12.remoteConfigTools),
|
|
45
|
+
storage: addFeaturePrefix("storage", index_13.storageTools),
|
|
46
|
+
developerknowledge: [],
|
|
44
47
|
};
|
|
45
48
|
const allToolsMap = new Map(Object.values(tools)
|
|
46
49
|
.flat()
|
|
47
50
|
.sort((a, b) => a.mcp.name.localeCompare(b.mcp.name))
|
|
48
51
|
.map((t) => [t.mcp.name, t]));
|
|
49
|
-
function getToolsByName(names) {
|
|
52
|
+
async function getToolsByName(names) {
|
|
50
53
|
const selectedTools = new Set();
|
|
54
|
+
const remoteTools = new Map((await getRemoteToolsByFeature()).map((t) => [t.mcp.name, t]));
|
|
51
55
|
for (const toolName of names) {
|
|
52
|
-
const tool = allToolsMap.get(toolName);
|
|
56
|
+
const tool = allToolsMap.get(toolName) || remoteTools.get(toolName);
|
|
53
57
|
if (tool) {
|
|
54
58
|
selectedTools.add(tool);
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
return Array.from(selectedTools);
|
|
58
62
|
}
|
|
59
|
-
function getToolsByFeature(serverFeatures) {
|
|
60
|
-
const features = new Set(serverFeatures?.length
|
|
63
|
+
async function getToolsByFeature(serverFeatures) {
|
|
64
|
+
const features = new Set(serverFeatures?.length
|
|
65
|
+
? serverFeatures
|
|
66
|
+
: Object.keys({ ...tools, ...index_1.ONEMCP_SERVERS }));
|
|
61
67
|
features.add("core");
|
|
62
|
-
|
|
68
|
+
const featureList = Array.from(features);
|
|
69
|
+
const localTools = featureList.flatMap((feature) => tools[feature] || []);
|
|
70
|
+
const remoteTools = await getRemoteToolsByFeature(featureList);
|
|
71
|
+
return [...localTools, ...remoteTools];
|
|
72
|
+
}
|
|
73
|
+
async function getRemoteToolsByFeature(features) {
|
|
74
|
+
const remoteToolsPromises = [];
|
|
75
|
+
const featureSet = new Set(features?.length ? features : Object.keys(index_1.ONEMCP_SERVERS));
|
|
76
|
+
for (const feature of featureSet) {
|
|
77
|
+
const server = index_1.ONEMCP_SERVERS[feature];
|
|
78
|
+
if (server) {
|
|
79
|
+
remoteToolsPromises.push(server.listTools());
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return Promise.all(remoteToolsPromises).then((tools) => tools.flat());
|
|
63
83
|
}
|
|
64
84
|
async function availableTools(ctx, activeFeatures, detectedFeatures, enabledTools) {
|
|
65
85
|
if (enabledTools?.length) {
|
|
@@ -68,7 +88,7 @@ async function availableTools(ctx, activeFeatures, detectedFeatures, enabledTool
|
|
|
68
88
|
if (activeFeatures?.length) {
|
|
69
89
|
return getToolsByFeature(activeFeatures);
|
|
70
90
|
}
|
|
71
|
-
const allTools = getToolsByFeature(detectedFeatures);
|
|
91
|
+
const allTools = await getToolsByFeature(detectedFeatures);
|
|
72
92
|
const availabilities = await Promise.all(allTools.map((t) => {
|
|
73
93
|
if (t.isAvailable) {
|
|
74
94
|
return t.isAvailable(ctx);
|
|
@@ -77,8 +97,8 @@ async function availableTools(ctx, activeFeatures, detectedFeatures, enabledTool
|
|
|
77
97
|
}));
|
|
78
98
|
return allTools.filter((_, i) => availabilities[i]);
|
|
79
99
|
}
|
|
80
|
-
function markdownDocsOfTools() {
|
|
81
|
-
const allTools = getToolsByFeature([]);
|
|
100
|
+
async function markdownDocsOfTools() {
|
|
101
|
+
const allTools = await getToolsByFeature([]);
|
|
82
102
|
let doc = `
|
|
83
103
|
| Tool Name | Feature Group | Description |
|
|
84
104
|
| --------- | ------------- | ----------- |`;
|
package/lib/mcp/types.js
CHANGED
|
@@ -5,7 +5,8 @@ const util_1 = require("../util");
|
|
|
5
5
|
const availability_1 = require("./crashlytics/availability");
|
|
6
6
|
const availability_2 = require("./apptesting/availability");
|
|
7
7
|
const DEFAULT_AVAILABILITY_CHECKS = {
|
|
8
|
-
core: async (
|
|
8
|
+
core: async () => true,
|
|
9
|
+
developerknowledge: async () => true,
|
|
9
10
|
firestore: (ctx) => (0, util_1.checkFeatureActive)("firestore", ctx.projectId, { config: ctx.config }),
|
|
10
11
|
storage: (ctx) => (0, util_1.checkFeatureActive)("storage", ctx.projectId, { config: ctx.config }),
|
|
11
12
|
dataconnect: (ctx) => (0, util_1.checkFeatureActive)("dataconnect", ctx.projectId, { config: ctx.config }),
|
package/lib/mcp/util.js
CHANGED
|
@@ -53,6 +53,7 @@ const SERVER_FEATURE_APIS = {
|
|
|
53
53
|
apptesting: (0, api_1.appDistributionOrigin)(),
|
|
54
54
|
apphosting: (0, api_1.apphostingOrigin)(),
|
|
55
55
|
database: (0, api_1.realtimeOrigin)(),
|
|
56
|
+
developerknowledge: (0, api_1.developerKnowledgeOrigin)(),
|
|
56
57
|
};
|
|
57
58
|
const DETECTED_API_FEATURES = {
|
|
58
59
|
core: undefined,
|
|
@@ -67,6 +68,7 @@ const DETECTED_API_FEATURES = {
|
|
|
67
68
|
apptesting: undefined,
|
|
68
69
|
apphosting: undefined,
|
|
69
70
|
database: undefined,
|
|
71
|
+
developerknowledge: undefined,
|
|
70
72
|
};
|
|
71
73
|
async function checkFeatureActive(feature, projectId, options) {
|
|
72
74
|
if (feature in (options?.config?.data || {}))
|