@exposify/firebase 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -22,7 +22,7 @@ root.
22
22
  From your Firebase project root (where `firebase.json` is):
23
23
 
24
24
  ```bash
25
- npx exposify-firebase init
25
+ npx @exposify/firebase init
26
26
  ```
27
27
 
28
28
  It reads `firebase.json` to find your functions directory and
@@ -70,7 +70,11 @@ broker as the authorization server, and the client sends the user through
70
70
  sign-in. Tool calls then reach Firestore with the `Authorization` the broker
71
71
  resolves for that user, never the broker token itself, so your rules still
72
72
  decide. Requests without a connection are refused rather
73
- than run anonymously; pass `authRequired: false` to allow them.
73
+ than run anonymously; pass `authRequired: false` to allow them. The
74
+ exception: when the project has no sign-in method yet (add the Firebase
75
+ preset in the dashboard), agents use the function signed out, as the
76
+ anonymous user, with no sign-in asked. The startup log says which it is
77
+ (`[agentready] How agents sign in: ...`).
74
78
 
75
79
  `auth: hostedBroker()` does the same explicitly. If the function is
76
80
  reached through a URL other than the one it sees (a custom domain or a
package/dist/cli.js CHANGED
@@ -75,7 +75,7 @@ function stripComments(source) {
75
75
  }
76
76
 
77
77
  // bin/init.ts
78
- var GENERATED_MARKER = "Generated by `exposify-firebase init`";
78
+ var GENERATED_MARKER = "Generated by `npx @exposify/firebase init`";
79
79
  function planInit(root) {
80
80
  const warnings = [];
81
81
  const firebaseJsonPath = join(root, "firebase.json");
@@ -194,7 +194,7 @@ function nextSteps(plan) {
194
194
  }
195
195
 
196
196
  // bin/cli.ts
197
- var USAGE = `Usage: exposify-firebase init [--dry-run]
197
+ var USAGE = `Usage: @exposify/firebase init [--dry-run]
198
198
 
199
199
  Run from your Firebase project root (where firebase.json is). Writes an MCP
200
200
  function to your functions source directory, with collections proposed from
package/dist/index.cjs CHANGED
@@ -104,7 +104,7 @@ function toolName(prefix, suffix, taken) {
104
104
  }
105
105
 
106
106
  // src/config.ts
107
- var LOG_PREFIX = "[exposify-firebase]";
107
+ var LOG_PREFIX = "[@exposify/firebase]";
108
108
  var WRITE_OPS = ["create", "update", "delete"];
109
109
  function parseWrites(writes = []) {
110
110
  const grants = /* @__PURE__ */ new Map();
@@ -654,7 +654,7 @@ function toNodeHandler(handle) {
654
654
  try {
655
655
  response = await handle(await toWebRequest(req));
656
656
  } catch (err) {
657
- console.error("[exposify-firebase] MCP request failed", err);
657
+ console.error("[@exposify/firebase] MCP request failed", err);
658
658
  response = Response.json({ error: "internal MCP server error" }, { status: 503 });
659
659
  }
660
660
  res.statusCode = response.status;
@@ -791,7 +791,7 @@ function createFirebaseMcpHandler(options = {}) {
791
791
  }
792
792
  };
793
793
  return buildFirebaseMcpServer({
794
- appName: "exposify-firebase",
794
+ appName: "@exposify/firebase",
795
795
  appVersion: "0.0.0",
796
796
  cfg,
797
797
  client: createFirestoreClient(baseUrl, authorization, fetchImpl),
@@ -807,13 +807,19 @@ function createFirebaseMcpHandler(options = {}) {
807
807
  if (!auth) return core;
808
808
  const brokerGate = authRequired ? (0, import_core2.createBrokerGate)(auth) : null;
809
809
  return async (req) => {
810
+ let open = false;
810
811
  if (brokerGate) {
811
812
  const own = (0, import_core2.publicRequestUrl)(req.url, req.headers);
812
813
  const isPrm = own.endsWith(import_core2.PRM_PATH);
813
814
  const resource = brokerGate.resourceFor(functionPublicUrl(isPrm ? own.slice(0, -import_core2.PRM_PATH.length) : own, functionName));
814
- if (isPrm) return brokerGate.metadataResponse(req.method, resource);
815
- const result = await brokerGate.check(req.headers, resource, `${resource}${import_core2.PRM_PATH}`);
816
- if (!result.ok) return result.response;
815
+ open = await (0, import_core2.reportAppLogin)(auth, resource, null, { stacks: ["firebase-admin"], why: "Firebase Auth sign-in for agents is the Firebase preset in the dashboard's sign-in methods.", log: logReady }) === "open";
816
+ if (open) {
817
+ if (isPrm) return new Response("not found", { status: 404 });
818
+ } else {
819
+ if (isPrm) return brokerGate.metadataResponse(req.method, resource);
820
+ const result = await brokerGate.check(req.headers, resource, `${resource}${import_core2.PRM_PATH}`);
821
+ if (!result.ok) return result.response;
822
+ }
817
823
  }
818
824
  let resolved;
819
825
  try {
@@ -822,7 +828,7 @@ function createFirebaseMcpHandler(options = {}) {
822
828
  console.error(`${LOG_PREFIX} auth resolver failed`, err);
823
829
  return Response.json({ error: "internal MCP server error" }, { status: 503 });
824
830
  }
825
- if (authRequired && !resolved.get("authorization")) {
831
+ if (authRequired && !open && !resolved.get("authorization")) {
826
832
  return Response.json({ error: "unauthorized" }, { status: 401, headers: { "www-authenticate": "Bearer" } });
827
833
  }
828
834
  resolvedAuth.set(req, resolved);
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  KnowledgeBase,
11
11
  PRM_PATH,
12
12
  publicRequestUrl,
13
+ reportAppLogin,
13
14
  startupLogEnabled
14
15
  } from "@exposify/core";
15
16
  import { loadDocsFromFs } from "@exposify/core/node";
@@ -83,7 +84,7 @@ function toolName(prefix, suffix, taken) {
83
84
  }
84
85
 
85
86
  // src/config.ts
86
- var LOG_PREFIX = "[exposify-firebase]";
87
+ var LOG_PREFIX = "[@exposify/firebase]";
87
88
  var WRITE_OPS = ["create", "update", "delete"];
88
89
  function parseWrites(writes = []) {
89
90
  const grants = /* @__PURE__ */ new Map();
@@ -633,7 +634,7 @@ function toNodeHandler(handle) {
633
634
  try {
634
635
  response = await handle(await toWebRequest(req));
635
636
  } catch (err) {
636
- console.error("[exposify-firebase] MCP request failed", err);
637
+ console.error("[@exposify/firebase] MCP request failed", err);
637
638
  response = Response.json({ error: "internal MCP server error" }, { status: 503 });
638
639
  }
639
640
  res.statusCode = response.status;
@@ -770,7 +771,7 @@ function createFirebaseMcpHandler(options = {}) {
770
771
  }
771
772
  };
772
773
  return buildFirebaseMcpServer({
773
- appName: "exposify-firebase",
774
+ appName: "@exposify/firebase",
774
775
  appVersion: "0.0.0",
775
776
  cfg,
776
777
  client: createFirestoreClient(baseUrl, authorization, fetchImpl),
@@ -786,13 +787,19 @@ function createFirebaseMcpHandler(options = {}) {
786
787
  if (!auth) return core;
787
788
  const brokerGate = authRequired ? createBrokerGate(auth) : null;
788
789
  return async (req) => {
790
+ let open = false;
789
791
  if (brokerGate) {
790
792
  const own = publicRequestUrl(req.url, req.headers);
791
793
  const isPrm = own.endsWith(PRM_PATH);
792
794
  const resource = brokerGate.resourceFor(functionPublicUrl(isPrm ? own.slice(0, -PRM_PATH.length) : own, functionName));
793
- if (isPrm) return brokerGate.metadataResponse(req.method, resource);
794
- const result = await brokerGate.check(req.headers, resource, `${resource}${PRM_PATH}`);
795
- if (!result.ok) return result.response;
795
+ open = await reportAppLogin(auth, resource, null, { stacks: ["firebase-admin"], why: "Firebase Auth sign-in for agents is the Firebase preset in the dashboard's sign-in methods.", log: logReady }) === "open";
796
+ if (open) {
797
+ if (isPrm) return new Response("not found", { status: 404 });
798
+ } else {
799
+ if (isPrm) return brokerGate.metadataResponse(req.method, resource);
800
+ const result = await brokerGate.check(req.headers, resource, `${resource}${PRM_PATH}`);
801
+ if (!result.ok) return result.response;
802
+ }
796
803
  }
797
804
  let resolved;
798
805
  try {
@@ -801,7 +808,7 @@ function createFirebaseMcpHandler(options = {}) {
801
808
  console.error(`${LOG_PREFIX} auth resolver failed`, err);
802
809
  return Response.json({ error: "internal MCP server error" }, { status: 503 });
803
810
  }
804
- if (authRequired && !resolved.get("authorization")) {
811
+ if (authRequired && !open && !resolved.get("authorization")) {
805
812
  return Response.json({ error: "unauthorized" }, { status: 401, headers: { "www-authenticate": "Bearer" } });
806
813
  }
807
814
  resolvedAuth.set(req, resolved);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exposify/firebase",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "license": "MIT",
5
5
  "engines": {
6
6
  "node": ">=20.19"
@@ -29,7 +29,7 @@
29
29
  "prepack": "yarn build"
30
30
  },
31
31
  "dependencies": {
32
- "@exposify/core": "0.3.13",
32
+ "@exposify/core": "0.3.16",
33
33
  "@modelcontextprotocol/sdk": "^1.12.0",
34
34
  "zod": "^3.24.0"
35
35
  },