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.
Files changed (67) hide show
  1. package/lib/api.js +3 -1
  2. package/lib/apiv2.js +6 -6
  3. package/lib/bin/mcp.js +1 -1
  4. package/lib/commands/deploy.js +3 -0
  5. package/lib/commands/init.js +5 -0
  6. package/lib/config.js +1 -0
  7. package/lib/dataconnect/client.js +2 -2
  8. package/lib/dataconnect/prompts.js +14 -0
  9. package/lib/deploy/auth/deploy.js +63 -0
  10. package/lib/deploy/auth/index.js +9 -0
  11. package/lib/deploy/auth/prepare.js +26 -0
  12. package/lib/deploy/auth/release.js +5 -0
  13. package/lib/deploy/dataconnect/release.js +11 -0
  14. package/lib/deploy/functions/backend.js +10 -0
  15. package/lib/deploy/functions/build.js +2 -2
  16. package/lib/deploy/functions/checkIam.js +3 -2
  17. package/lib/deploy/functions/deploy.js +4 -2
  18. package/lib/deploy/functions/prepare.js +5 -2
  19. package/lib/deploy/functions/prepareFunctionsUpload.js +7 -5
  20. package/lib/deploy/functions/release/fabricator.js +96 -15
  21. package/lib/deploy/functions/release/index.js +2 -1
  22. package/lib/deploy/functions/runtimes/dart.js +42 -0
  23. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +4 -1
  24. package/lib/deploy/functions/runtimes/index.js +9 -1
  25. package/lib/deploy/functions/runtimes/supported/types.js +6 -0
  26. package/lib/deploy/index.js +2 -0
  27. package/lib/emulator/auth/index.js +23 -17
  28. package/lib/emulator/auth/operations.js +9 -1
  29. package/lib/emulator/downloadableEmulatorInfo.json +31 -31
  30. package/lib/emulator/hubExport.js +15 -1
  31. package/lib/gcp/cloudbilling.js +6 -3
  32. package/lib/gcp/runv2.js +75 -3
  33. package/lib/gemini/fdcExperience.js +0 -11
  34. package/lib/init/features/auth.js +72 -0
  35. package/lib/init/features/dataconnect/resolver.js +17 -3
  36. package/lib/init/features/functions/index.js +22 -14
  37. package/lib/init/features/functions/javascript.js +18 -3
  38. package/lib/init/features/functions/typescript.js +20 -3
  39. package/lib/init/features/functions/utils.js +10 -0
  40. package/lib/init/features/genkit/index.js +3 -2
  41. package/lib/init/features/index.js +6 -2
  42. package/lib/init/index.js +11 -1
  43. package/lib/management/provisioning/provision.js +3 -0
  44. package/lib/management/provisioning/types.js +7 -0
  45. package/lib/mcp/onemcp/index.js +8 -0
  46. package/lib/mcp/onemcp/onemcp_server.js +77 -0
  47. package/lib/mcp/prompts/index.js +1 -0
  48. package/lib/mcp/resources/guides/init_auth.js +19 -2
  49. package/lib/mcp/tools/apptesting/tests.js +6 -4
  50. package/lib/mcp/tools/core/init.js +31 -0
  51. package/lib/mcp/tools/index.js +52 -32
  52. package/lib/mcp/types.js +1 -0
  53. package/lib/mcp/util/availability.js +2 -1
  54. package/lib/mcp/util.js +2 -0
  55. package/lib/tsconfig.publish.tsbuildinfo +1 -1
  56. package/package.json +1 -1
  57. package/schema/firebase-config.json +41 -0
  58. package/templates/init/apptesting/smoke_test.yaml +1 -1
  59. package/templates/init/dataconnect/secondary_schema.gql +8 -0
  60. package/templates/init/functions/javascript/index-ongraphrequest.js +36 -0
  61. package/templates/init/functions/javascript/package-ongraphrequest.lint.json +28 -0
  62. package/templates/init/functions/javascript/package-ongraphrequest.nolint.json +25 -0
  63. package/templates/init/functions/python/requirements.txt +1 -1
  64. package/templates/init/functions/typescript/index-ongraphrequest.ts +44 -0
  65. package/templates/init/functions/typescript/package-ongraphrequest.lint.json +33 -0
  66. package/templates/init/functions/typescript/package-ongraphrequest.nolint.json +27 -0
  67. 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}/package.json`, PACKAGE_NO_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
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
- await config.askWriteProjectFile(`${setup.functions.source}/src/index.ts`, INDEX_TEMPLATE);
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 functions_1 = require("../functions");
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 (0, functions_1.doSetup)(setup, config, options);
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.functions = exports.firestoreActuate = exports.firestoreAskQuestions = exports.databaseActuate = exports.databaseAskQuestions = exports.account = void 0;
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, "functions", { enumerable: true, get: function () { return functions_1.doSetup; } });
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
- { name: "functions", doSetup: features.functions },
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;
@@ -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
- - Guide developers to enable authentication providers (Email/Password, Google Sign-in, etc.) in the [Firebase Auth Console](https://console.firebase.google.com/)
22
- - Ask developers to confirm which authentication method they selected before proceeding
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
- return (0, util_1.toContent)({
96
- devices,
97
- releaseTest,
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,
@@ -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("./apphosting/index");
7
- const index_2 = require("./apptesting/index");
8
- const index_3 = require("./auth/index");
9
- const index_4 = require("./core/index");
10
- const index_5 = require("./crashlytics/index");
11
- const index_6 = require("./dataconnect/index");
12
- const index_7 = require("./firestore/index");
13
- const index_8 = require("./functions/index");
14
- const index_9 = require("./messaging/index");
15
- const index_10 = require("./realtime_database/index");
16
- const index_11 = require("./remoteconfig/index");
17
- const index_12 = require("./storage/index");
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", index_1.appHostingTools),
33
- apptesting: addFeaturePrefix("apptesting", index_2.apptestingTools),
34
- auth: addFeaturePrefix("auth", index_3.authTools),
35
- core: addFeaturePrefix("firebase", index_4.coreTools),
36
- crashlytics: addFeaturePrefix("crashlytics", index_5.crashlyticsTools),
37
- database: addFeaturePrefix("realtimedatabase", index_10.realtimeDatabaseTools),
38
- dataconnect: addFeaturePrefix("dataconnect", index_6.dataconnectTools),
39
- firestore: addFeaturePrefix("firestore", index_7.firestoreTools),
40
- functions: addFeaturePrefix("functions", index_8.functionsTools),
41
- messaging: addFeaturePrefix("messaging", index_9.messagingTools),
42
- remoteconfig: addFeaturePrefix("remoteconfig", index_11.remoteConfigTools),
43
- storage: addFeaturePrefix("storage", index_12.storageTools),
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 ? serverFeatures : Object.keys(tools));
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
- return Array.from(features).flatMap((feature) => tools[feature] || []);
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
@@ -14,4 +14,5 @@ exports.SERVER_FEATURES = [
14
14
  "apptesting",
15
15
  "apphosting",
16
16
  "database",
17
+ "developerknowledge",
17
18
  ];
@@ -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 (ctx) => true,
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 || {}))