firebase-mcp 0.3.0 → 0.3.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.
Files changed (133) hide show
  1. package/README.md +78 -44
  2. package/dist/config/index.js +1 -1
  3. package/dist/config/index.js.map +1 -1
  4. package/dist/config/index.test.d.ts +2 -0
  5. package/dist/config/index.test.d.ts.map +1 -0
  6. package/dist/config/index.test.js +98 -0
  7. package/dist/config/index.test.js.map +1 -0
  8. package/dist/server/index.d.ts +2 -0
  9. package/dist/server/index.d.ts.map +1 -1
  10. package/dist/server/index.js +38 -42
  11. package/dist/server/index.js.map +1 -1
  12. package/dist/task/index.test.d.ts +2 -0
  13. package/dist/task/index.test.d.ts.map +1 -0
  14. package/dist/task/index.test.js +318 -0
  15. package/dist/task/index.test.js.map +1 -0
  16. package/dist/tools/auth/index.d.ts +3 -3
  17. package/dist/tools/auth/index.d.ts.map +1 -1
  18. package/dist/tools/auth/index.js +3 -3
  19. package/dist/tools/auth/index.js.map +1 -1
  20. package/dist/tools/auth/{get_user.d.ts → operations/get_user.d.ts} +2 -2
  21. package/dist/tools/auth/operations/get_user.d.ts.map +1 -0
  22. package/dist/tools/auth/{get_user.js → operations/get_user.js} +2 -2
  23. package/dist/tools/auth/operations/get_user.js.map +1 -0
  24. package/dist/tools/auth/{list_users.d.ts → operations/list_users.d.ts} +2 -2
  25. package/dist/tools/auth/operations/list_users.d.ts.map +1 -0
  26. package/dist/tools/auth/{list_users.js → operations/list_users.js} +2 -2
  27. package/dist/tools/auth/operations/list_users.js.map +1 -0
  28. package/dist/tools/auth/{read.d.ts → tool.d.ts} +2 -2
  29. package/dist/tools/auth/{read.d.ts.map → tool.d.ts.map} +1 -1
  30. package/dist/tools/auth/{read.js → tool.js} +3 -3
  31. package/dist/tools/auth/{read.js.map → tool.js.map} +1 -1
  32. package/dist/tools/firestore/index.d.ts +13 -12
  33. package/dist/tools/firestore/index.d.ts.map +1 -1
  34. package/dist/tools/firestore/index.js +13 -12
  35. package/dist/tools/firestore/index.js.map +1 -1
  36. package/dist/tools/firestore/{aggregate_collection.d.ts → operations/aggregate_collection.d.ts} +4 -4
  37. package/dist/tools/firestore/operations/aggregate_collection.d.ts.map +1 -0
  38. package/dist/tools/firestore/{aggregate_collection.js → operations/aggregate_collection.js} +7 -2
  39. package/dist/tools/firestore/operations/aggregate_collection.js.map +1 -0
  40. package/dist/tools/firestore/{count_documents.d.ts → operations/count_documents.d.ts} +4 -4
  41. package/dist/tools/firestore/operations/count_documents.d.ts.map +1 -0
  42. package/dist/tools/firestore/{count_documents.js → operations/count_documents.js} +7 -2
  43. package/dist/tools/firestore/operations/count_documents.js.map +1 -0
  44. package/dist/tools/firestore/operations/distinct_values.d.ts +59 -0
  45. package/dist/tools/firestore/operations/distinct_values.d.ts.map +1 -0
  46. package/dist/tools/firestore/operations/distinct_values.js +173 -0
  47. package/dist/tools/firestore/operations/distinct_values.js.map +1 -0
  48. package/dist/tools/firestore/{get_collection_schema.d.ts → operations/get_collection_schema.d.ts} +3 -3
  49. package/dist/tools/firestore/operations/get_collection_schema.d.ts.map +1 -0
  50. package/dist/tools/firestore/{get_collection_schema.js → operations/get_collection_schema.js} +6 -1
  51. package/dist/tools/firestore/operations/get_collection_schema.js.map +1 -0
  52. package/dist/tools/firestore/{get_document.d.ts → operations/get_document.d.ts} +4 -3
  53. package/dist/tools/firestore/operations/get_document.d.ts.map +1 -0
  54. package/dist/tools/firestore/{get_document.js → operations/get_document.js} +20 -9
  55. package/dist/tools/firestore/operations/get_document.js.map +1 -0
  56. package/dist/tools/firestore/{get_many_documents.d.ts → operations/get_many_documents.d.ts} +3 -3
  57. package/dist/tools/firestore/operations/get_many_documents.d.ts.map +1 -0
  58. package/dist/tools/firestore/{get_many_documents.js → operations/get_many_documents.js} +13 -2
  59. package/dist/tools/firestore/operations/get_many_documents.js.map +1 -0
  60. package/dist/tools/firestore/{list_collections.d.ts → operations/list_collections.d.ts} +3 -3
  61. package/dist/tools/firestore/operations/list_collections.d.ts.map +1 -0
  62. package/dist/tools/firestore/{list_collections.js → operations/list_collections.js} +6 -1
  63. package/dist/tools/firestore/operations/list_collections.js.map +1 -0
  64. package/dist/tools/firestore/{list_documents.d.ts → operations/list_documents.d.ts} +4 -4
  65. package/dist/tools/firestore/operations/list_documents.d.ts.map +1 -0
  66. package/dist/tools/firestore/{list_documents.js → operations/list_documents.js} +19 -21
  67. package/dist/tools/firestore/operations/list_documents.js.map +1 -0
  68. package/dist/tools/firestore/{list_indexes.d.ts → operations/list_indexes.d.ts} +2 -2
  69. package/dist/tools/firestore/operations/list_indexes.d.ts.map +1 -0
  70. package/dist/tools/firestore/{list_indexes.js → operations/list_indexes.js} +1 -1
  71. package/dist/tools/firestore/operations/list_indexes.js.map +1 -0
  72. package/dist/tools/firestore/{query_collection.d.ts → operations/query_collection.d.ts} +4 -4
  73. package/dist/tools/firestore/operations/query_collection.d.ts.map +1 -0
  74. package/dist/tools/firestore/{query_collection.js → operations/query_collection.js} +7 -2
  75. package/dist/tools/firestore/operations/query_collection.js.map +1 -0
  76. package/dist/tools/firestore/{query_collection_group.d.ts → operations/query_collection_group.d.ts} +4 -4
  77. package/dist/tools/firestore/operations/query_collection_group.d.ts.map +1 -0
  78. package/dist/tools/firestore/{query_collection_group.js → operations/query_collection_group.js} +2 -2
  79. package/dist/tools/firestore/operations/query_collection_group.js.map +1 -0
  80. package/dist/tools/firestore/{read_collections.d.ts → operations/read_collections.d.ts} +3 -3
  81. package/dist/tools/firestore/operations/read_collections.d.ts.map +1 -0
  82. package/dist/tools/firestore/{read_collections.js → operations/read_collections.js} +7 -2
  83. package/dist/tools/firestore/operations/read_collections.js.map +1 -0
  84. package/dist/tools/firestore/{read.d.ts → tool.d.ts} +32 -8
  85. package/dist/tools/firestore/tool.d.ts.map +1 -0
  86. package/dist/tools/firestore/{read.js → tool.js} +73 -27
  87. package/dist/tools/firestore/tool.js.map +1 -0
  88. package/dist/tools/firestore/utils/paths.d.ts +14 -0
  89. package/dist/tools/firestore/utils/paths.d.ts.map +1 -0
  90. package/dist/tools/firestore/utils/paths.js +39 -0
  91. package/dist/tools/firestore/utils/paths.js.map +1 -0
  92. package/dist/tools/firestore/utils/paths.test.d.ts +2 -0
  93. package/dist/tools/firestore/utils/paths.test.d.ts.map +1 -0
  94. package/dist/tools/firestore/utils/paths.test.js +68 -0
  95. package/dist/tools/firestore/utils/paths.test.js.map +1 -0
  96. package/dist/tools/firestore/utils/types.d.ts.map +1 -0
  97. package/dist/tools/firestore/{types.js → utils/types.js} +1 -1
  98. package/dist/tools/firestore/utils/types.js.map +1 -0
  99. package/dist/tools/index.d.ts.map +1 -1
  100. package/dist/tools/index.js +1 -0
  101. package/dist/tools/index.js.map +1 -1
  102. package/package.json +5 -2
  103. package/dist/tools/auth/get_user.d.ts.map +0 -1
  104. package/dist/tools/auth/get_user.js.map +0 -1
  105. package/dist/tools/auth/list_users.d.ts.map +0 -1
  106. package/dist/tools/auth/list_users.js.map +0 -1
  107. package/dist/tools/firestore/aggregate_collection.d.ts.map +0 -1
  108. package/dist/tools/firestore/aggregate_collection.js.map +0 -1
  109. package/dist/tools/firestore/count_documents.d.ts.map +0 -1
  110. package/dist/tools/firestore/count_documents.js.map +0 -1
  111. package/dist/tools/firestore/get_collection_schema.d.ts.map +0 -1
  112. package/dist/tools/firestore/get_collection_schema.js.map +0 -1
  113. package/dist/tools/firestore/get_document.d.ts.map +0 -1
  114. package/dist/tools/firestore/get_document.js.map +0 -1
  115. package/dist/tools/firestore/get_many_documents.d.ts.map +0 -1
  116. package/dist/tools/firestore/get_many_documents.js.map +0 -1
  117. package/dist/tools/firestore/list_collections.d.ts.map +0 -1
  118. package/dist/tools/firestore/list_collections.js.map +0 -1
  119. package/dist/tools/firestore/list_documents.d.ts.map +0 -1
  120. package/dist/tools/firestore/list_documents.js.map +0 -1
  121. package/dist/tools/firestore/list_indexes.d.ts.map +0 -1
  122. package/dist/tools/firestore/list_indexes.js.map +0 -1
  123. package/dist/tools/firestore/query_collection.d.ts.map +0 -1
  124. package/dist/tools/firestore/query_collection.js.map +0 -1
  125. package/dist/tools/firestore/query_collection_group.d.ts.map +0 -1
  126. package/dist/tools/firestore/query_collection_group.js.map +0 -1
  127. package/dist/tools/firestore/read.d.ts.map +0 -1
  128. package/dist/tools/firestore/read.js.map +0 -1
  129. package/dist/tools/firestore/read_collections.d.ts.map +0 -1
  130. package/dist/tools/firestore/read_collections.js.map +0 -1
  131. package/dist/tools/firestore/types.d.ts.map +0 -1
  132. package/dist/tools/firestore/types.js.map +0 -1
  133. /package/dist/tools/firestore/{types.d.ts → utils/types.d.ts} +0 -0
package/README.md CHANGED
@@ -4,39 +4,53 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that ex
4
4
 
5
5
  ## Features
6
6
 
7
- - **11 Firestore read tools** covering collections, documents, queries, aggregations, and schema inference
8
- - **2 Firebase Auth tools** — look up users by UID or email, list users with pagination
7
+ - **12 Firestore read operations** covering collections, documents, queries, aggregations, distinct value counts, and schema inference
8
+ - **2 Firebase Auth operations** — look up users by UID or email, list users with pagination
9
+ - **Multi-project support** — configure multiple Firebase projects in one config file; each tool call targets a specific project via `projectId`
9
10
  - **Glob-based access control** — allow/deny rules evaluated per Firestore path before any read is performed
10
11
  - **Pagination** on `query_collection`, `read_collection`, and `list_users` via cursor-based tokens
11
12
  - **Batch fetching** with configurable `maxBatchFetchSize`
12
13
  - **Schema inference** via `get_collection_schema` — samples documents and infers field types without reading the full collection
14
+ - **Distinct value counts** via `distinct_values` — count occurrences of unique field values across a collection or collection group
13
15
  - **Normalized output** — Firestore Timestamps, GeoPoints, and DocumentReferences are converted to JSON-serializable values on all tools
14
16
  - Zero runtime state — each tool call hits Firebase directly through the Admin SDK
15
17
 
16
18
  ## Tools
17
19
 
18
- ### Firestore
19
-
20
- | Tool | Description |
21
- | ------------------------ | ----------------------------------------------------------------------------------------------------------- |
22
- | `list_collections` | List root collections or subcollections of a document. Optionally include document counts. |
23
- | `list_documents` | List all document IDs in a collection, including phantom documents. Optionally include subcollection names. |
24
- | `read_collection` | Read documents from a collection with optional phantom-doc surfacing. |
25
- | `get_document` | Fetch a single document by path. |
26
- | `get_many_documents` | Batch-fetch documents by a list of paths or a collection + ID list. |
27
- | `query_collection` | Query with filters, ordering, limit, and pagination. |
28
- | `query_collection_group` | Query across all collections sharing the same name, regardless of parent path. |
29
- | `count_documents` | Server-side document count with optional filters. |
30
- | `aggregate_collection` | Native `sum()` and `avg()` aggregations without fetching documents. |
31
- | `get_collection_schema` | Sample a collection from both ends and infer field types. |
32
- | `list_indexes` | List Firestore indexes for the project. |
33
-
34
- ### Auth
35
-
36
- | Tool | Description |
37
- | ------------ | ---------------------------------------------------------------------- |
38
- | `get_user` | Fetch a Firebase Auth user by UID or email. |
39
- | `list_users` | List Firebase Auth users with optional pagination via `nextPageToken`. |
20
+ ### Config
21
+
22
+ | Tool | Description |
23
+ | --------------- | --------------------------------------------------------------------------------------------------------------------------- |
24
+ | `get_config` | Returns the current in-memory config, listing all available projects. Call this first to discover valid `projectId` values. |
25
+ | `reload_config` | Re-reads `firebase-mcp.json` from disk and evicts all cached project runtimes. |
26
+
27
+ ### Firestore (`firestore_read`)
28
+
29
+ All operations are dispatched through the single `firestore_read` tool via the `operation` field. Every call requires a `projectId` matching a key in `firebase-mcp.json`.
30
+
31
+ | Operation | Description |
32
+ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
33
+ | `list_collections` | List root collections or subcollections of a document. Optionally include document counts. |
34
+ | `list_documents` | List all document IDs in a collection, including phantom documents. Optionally include subcollection names. |
35
+ | `read_collection` | Read documents from a collection with optional phantom-doc surfacing. |
36
+ | `get_document` | Fetch a single document by path. |
37
+ | `get_many_documents` | Batch-fetch documents by a list of paths or a collection + ID list. |
38
+ | `query_collection` | Query with filters, ordering, limit, and pagination. |
39
+ | `query_collection_group` | Query across all collections sharing the same name, regardless of parent path. |
40
+ | `count_documents` | Server-side document count with optional filters. |
41
+ | `aggregate_collection` | Native `sum()`, `avg()`, and `count()` aggregations without fetching documents. |
42
+ | `get_collection_schema` | Sample a collection from both ends and infer field types. |
43
+ | `list_indexes` | List Firestore composite indexes for the project. |
44
+ | `distinct_values` | Count occurrences of each unique value (or value combination) of one or more fields across a collection or collection group. |
45
+
46
+ ### Auth (`auth_read`)
47
+
48
+ All operations are dispatched through the single `auth_read` tool via the `operation` field. Every call requires a `projectId`.
49
+
50
+ | Operation | Description |
51
+ | ------------ | ------------------------------------------------------------------ |
52
+ | `get_user` | Fetch a Firebase Auth user by UID or email. |
53
+ | `list_users` | List Firebase Auth users with optional pagination via `pageToken`. |
40
54
 
41
55
  ## Requirements
42
56
 
@@ -48,26 +62,43 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that ex
48
62
 
49
63
  **1. Create `firebase-mcp.json`**
50
64
 
65
+ The config supports multiple projects under a `projects` key. Each key becomes the `projectId` value you pass to tool calls.
66
+
51
67
  ```json
52
68
  {
53
- "firebase": {
54
- "projectId": "your-project-id",
55
- "serviceAccountPath": "secrets/serviceAccount.json"
56
- },
57
- "firestore": {
58
- "rules": {
59
- "allow": ["**"],
60
- "deny": []
61
- },
62
- "maxCollectionReadSize": 10,
63
- "maxBatchFetchSize": 200
69
+ "projects": {
70
+ "my-app": {
71
+ "firebase": {
72
+ "projectId": "your-firebase-project-id",
73
+ "serviceAccountPath": "secrets/serviceAccount.json"
74
+ },
75
+ "firestore": {
76
+ "rules": {
77
+ "allow": ["**"],
78
+ "deny": []
79
+ },
80
+ "maxCollectionReadSize": 100,
81
+ "maxBatchFetchSize": 200
82
+ }
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
88
+ To configure multiple projects, add additional keys under `projects`:
89
+
90
+ ```json
91
+ {
92
+ "projects": {
93
+ "prod": { "firebase": { ... }, "firestore": { ... } },
94
+ "staging": { "firebase": { ... }, "firestore": { ... } }
64
95
  }
65
96
  }
66
97
  ```
67
98
 
68
99
  **2. Add your service account key**
69
100
 
70
- Place your Firebase service account JSON at any path you prefer — you'll reference it in `firebase-mcp.json` above.
101
+ Place your Firebase service account JSON at any path you prefer — you'll reference it in `firebase-mcp.json` above. Paths are resolved relative to the working directory when the server starts, or you can use an absolute path.
71
102
 
72
103
  **3. Wire it into your MCP host**
73
104
 
@@ -75,14 +106,15 @@ See the [Connecting to Cursor](#connecting-to-cursor) section below — no insta
75
106
 
76
107
  ## Configuration
77
108
 
78
- | Field | Type | Default | Description |
79
- | --------------------------------- | ---------- | ------- | ---------------------------------------------------------- |
80
- | `firebase.projectId` | `string` | — | Firebase project ID |
81
- | `firebase.serviceAccountPath` | `string` | — | Path to service account JSON (relative to CWD or absolute) |
82
- | `firestore.rules.allow` | `string[]` | — | Glob patterns for allowed Firestore paths |
83
- | `firestore.rules.deny` | `string[]` | — | Glob patterns for denied Firestore paths (evaluated first) |
84
- | `firestore.maxCollectionReadSize` | `number` | `10` | Default document limit for collection reads |
85
- | `firestore.maxBatchFetchSize` | `number` | `200` | Maximum documents per batch fetch |
109
+ | Field | Type | Default | Description |
110
+ | ------------------------------------------------ | ---------- | ------- | ---------------------------------------------------------- |
111
+ | `projects` | `object` | — | Map of project keys to project configs |
112
+ | `projects.<key>.firebase.projectId` | `string` | — | Firebase project ID |
113
+ | `projects.<key>.firebase.serviceAccountPath` | `string` | — | Path to service account JSON (relative to CWD or absolute) |
114
+ | `projects.<key>.firestore.rules.allow` | `string[]` | — | Glob patterns for allowed Firestore paths |
115
+ | `projects.<key>.firestore.rules.deny` | `string[]` | | Glob patterns for denied Firestore paths (evaluated first) |
116
+ | `projects.<key>.firestore.maxCollectionReadSize` | `number` | `100` | Default document limit for collection reads |
117
+ | `projects.<key>.firestore.maxBatchFetchSize` | `number` | `200` | Maximum documents per batch fetch |
86
118
 
87
119
  A custom config path can be passed at startup:
88
120
 
@@ -120,6 +152,8 @@ Add to your MCP config (e.g. `.cursor/mcp.json`):
120
152
 
121
153
  `npx -y` will download and cache the package automatically on first run. No manual installation needed.
122
154
 
155
+ `firestore_read` and `auth_read` are safe to add to Cursor's tool allowlist for unattended use. `get_config` and `reload_config` are also read-only and safe to allowlist.
156
+
123
157
  ## License
124
158
 
125
159
  MIT
@@ -29,7 +29,7 @@ const FirestoreRulesSchema = zod_1.z.object({
29
29
  });
30
30
  const FirestoreConfigSchema = zod_1.z.object({
31
31
  rules: FirestoreRulesSchema,
32
- maxCollectionReadSize: zod_1.z.number().default(10),
32
+ maxCollectionReadSize: zod_1.z.number().default(100),
33
33
  maxBatchFetchSize: zod_1.z.number().default(200),
34
34
  });
35
35
  exports.ProjectConfigSchema = zod_1.z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":";;;;;;AAAA,wDAAgC;AAChC,qCAAuC;AACvC,yCAAoC;AACpC,6BAAwB;AAExB,kCAA+B;AAE/B,MAAa,WAAY,SAAQ,KAAK;IAEE;IAD7B,IAAI,GAAG,aAAsB,CAAC;IACvC,YAAY,OAAe,EAAW,KAAe;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,UAAK,GAAL,KAAK,CAAU;QAEnD,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAND,kCAMC;AAED,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE;IACrB,kBAAkB,EAAE,OAAC,CAAC,MAAM,EAAE;CAC/B,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,KAAK,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;CAC1B,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,oBAAoB;IAC3B,qBAAqB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7C,iBAAiB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;CAC3C,CAAC,CAAC;AAEU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,QAAQ,EAAE,oBAAoB;IAC9B,SAAS,EAAE,qBAAqB;CACjC,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/B,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,2BAAmB,CAAC;CACpD,CAAC,CAAC;AAKI,MAAM,UAAU,GAAG,CAAC,UAAkB,EAAgC,EAAE,CAC7E,WAAI,CAAC,OAAO,CAAC;IACX,GAAG,EAAE,GAAG,EAAE;QACR,MAAM,YAAY,GAAG,IAAA,mBAAO,EAAC,UAAU,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,IAAA,sBAAY,EAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QACxC,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,WAAW,CAAC,0BAA0B,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,KAAK,YAAY,WAAW;YAAE,OAAO,KAAK,CAAC;QAC/C,OAAO,IAAI,WAAW,CAAC,0BAA0B,UAAU,EAAE,EAAE,KAAK,CAAC,CAAC;IACxE,CAAC;CACF,CAAC,CAAC;AAhBQ,QAAA,UAAU,cAgBlB;AAEE,MAAM,aAAa,GAAG,GAAW,EAAE;IACxC,MAAM,IAAI,GAAG,IAAA,kBAAQ,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,qBAAqB,CAAC;AACjD,CAAC,CAAC;AAHW,QAAA,aAAa,iBAGxB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":";;;;;;AAAA,wDAAgC;AAChC,qCAAuC;AACvC,yCAAoC;AACpC,6BAAwB;AAExB,kCAA+B;AAE/B,MAAa,WAAY,SAAQ,KAAK;IAEE;IAD7B,IAAI,GAAG,aAAsB,CAAC;IACvC,YAAY,OAAe,EAAW,KAAe;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,UAAK,GAAL,KAAK,CAAU;QAEnD,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAND,kCAMC;AAED,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE;IACrB,kBAAkB,EAAE,OAAC,CAAC,MAAM,EAAE;CAC/B,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,KAAK,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;CAC1B,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,oBAAoB;IAC3B,qBAAqB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;IAC9C,iBAAiB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;CAC3C,CAAC,CAAC;AAEU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,QAAQ,EAAE,oBAAoB;IAC9B,SAAS,EAAE,qBAAqB;CACjC,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/B,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,2BAAmB,CAAC;CACpD,CAAC,CAAC;AAKI,MAAM,UAAU,GAAG,CAAC,UAAkB,EAAgC,EAAE,CAC7E,WAAI,CAAC,OAAO,CAAC;IACX,GAAG,EAAE,GAAG,EAAE;QACR,MAAM,YAAY,GAAG,IAAA,mBAAO,EAAC,UAAU,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,IAAA,sBAAY,EAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QACxC,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,WAAW,CAAC,0BAA0B,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,KAAK,YAAY,WAAW;YAAE,OAAO,KAAK,CAAC;QAC/C,OAAO,IAAI,WAAW,CAAC,0BAA0B,UAAU,EAAE,EAAE,KAAK,CAAC,CAAC;IACxE,CAAC;CACF,CAAC,CAAC;AAhBQ,QAAA,UAAU,cAgBlB;AAEE,MAAM,aAAa,GAAG,GAAW,EAAE;IACxC,MAAM,IAAI,GAAG,IAAA,kBAAQ,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,qBAAqB,CAAC;AACjD,CAAC,CAAC;AAHW,QAAA,aAAa,iBAGxB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/config/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const index_1 = require("./index");
5
+ // ---------------------------------------------------------------------------
6
+ // ProjectConfigSchema — the innermost validated unit, no file I/O needed
7
+ // ---------------------------------------------------------------------------
8
+ const validProject = {
9
+ firebase: {
10
+ projectId: 'my-project',
11
+ serviceAccountPath: '/path/to/sa.json',
12
+ },
13
+ firestore: {
14
+ rules: {
15
+ allow: ['**'],
16
+ deny: [],
17
+ },
18
+ },
19
+ };
20
+ (0, vitest_1.describe)('ProjectConfigSchema', () => {
21
+ (0, vitest_1.it)('parses a fully valid project config', () => {
22
+ const result = index_1.ProjectConfigSchema.safeParse(validProject);
23
+ (0, vitest_1.expect)(result.success).toBe(true);
24
+ });
25
+ (0, vitest_1.it)('applies default maxCollectionReadSize of 100', () => {
26
+ const result = index_1.ProjectConfigSchema.safeParse(validProject);
27
+ (0, vitest_1.expect)(result.success).toBe(true);
28
+ if (result.success) {
29
+ (0, vitest_1.expect)(result.data.firestore.maxCollectionReadSize).toBe(100);
30
+ }
31
+ });
32
+ (0, vitest_1.it)('applies default maxBatchFetchSize of 200', () => {
33
+ const result = index_1.ProjectConfigSchema.safeParse(validProject);
34
+ (0, vitest_1.expect)(result.success).toBe(true);
35
+ if (result.success) {
36
+ (0, vitest_1.expect)(result.data.firestore.maxBatchFetchSize).toBe(200);
37
+ }
38
+ });
39
+ (0, vitest_1.it)('accepts explicit maxCollectionReadSize and maxBatchFetchSize', () => {
40
+ const input = {
41
+ ...validProject,
42
+ firestore: {
43
+ ...validProject.firestore,
44
+ maxCollectionReadSize: 50,
45
+ maxBatchFetchSize: 75,
46
+ },
47
+ };
48
+ const result = index_1.ProjectConfigSchema.safeParse(input);
49
+ (0, vitest_1.expect)(result.success).toBe(true);
50
+ if (result.success) {
51
+ (0, vitest_1.expect)(result.data.firestore.maxCollectionReadSize).toBe(50);
52
+ (0, vitest_1.expect)(result.data.firestore.maxBatchFetchSize).toBe(75);
53
+ }
54
+ });
55
+ (0, vitest_1.it)('fails when firebase.projectId is missing', () => {
56
+ const input = {
57
+ ...validProject,
58
+ firebase: { serviceAccountPath: '/path/to/sa.json' },
59
+ };
60
+ const result = index_1.ProjectConfigSchema.safeParse(input);
61
+ (0, vitest_1.expect)(result.success).toBe(false);
62
+ });
63
+ (0, vitest_1.it)('fails when firebase.serviceAccountPath is missing', () => {
64
+ const input = {
65
+ ...validProject,
66
+ firebase: { projectId: 'my-project' },
67
+ };
68
+ const result = index_1.ProjectConfigSchema.safeParse(input);
69
+ (0, vitest_1.expect)(result.success).toBe(false);
70
+ });
71
+ (0, vitest_1.it)('fails when firestore.rules is missing', () => {
72
+ const input = { ...validProject, firestore: {} };
73
+ const result = index_1.ProjectConfigSchema.safeParse(input);
74
+ (0, vitest_1.expect)(result.success).toBe(false);
75
+ });
76
+ (0, vitest_1.it)('fails when firestore.rules.allow is not an array', () => {
77
+ const input = {
78
+ ...validProject,
79
+ firestore: { rules: { allow: '**', deny: [] } },
80
+ };
81
+ const result = index_1.ProjectConfigSchema.safeParse(input);
82
+ (0, vitest_1.expect)(result.success).toBe(false);
83
+ });
84
+ (0, vitest_1.it)('fails when firestore.rules.deny is not an array', () => {
85
+ const input = {
86
+ ...validProject,
87
+ firestore: { rules: { allow: ['**'], deny: 'none' } },
88
+ };
89
+ const result = index_1.ProjectConfigSchema.safeParse(input);
90
+ (0, vitest_1.expect)(result.success).toBe(false);
91
+ });
92
+ (0, vitest_1.it)('fails when the top-level object is missing', () => {
93
+ (0, vitest_1.expect)(index_1.ProjectConfigSchema.safeParse(null).success).toBe(false);
94
+ (0, vitest_1.expect)(index_1.ProjectConfigSchema.safeParse(undefined).success).toBe(false);
95
+ (0, vitest_1.expect)(index_1.ProjectConfigSchema.safeParse('string').success).toBe(false);
96
+ });
97
+ });
98
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/config/index.test.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,8 @@ export declare class FirebaseMcpServer {
10
10
  private readonly configPath;
11
11
  constructor();
12
12
  start(): Promise<void>;
13
+ private handleToolCall;
14
+ private reloadAppConfig;
13
15
  private getOrInitProject;
14
16
  }
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAkBA,qBAAa,cAAe,SAAQ,KAAK;IAIrC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;IAH1B,QAAQ,CAAC,IAAI,EAAG,gBAAgB,CAAU;gBAExC,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAeD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA8C;IAC9E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;;IAU9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4F5B,OAAO,CAAC,gBAAgB;CAgBzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAkBA,qBAAa,cAAe,SAAQ,KAAK;IAIrC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;IAH1B,QAAQ,CAAC,IAAI,EAAG,gBAAgB,CAAU;gBAExC,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAeD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA8C;IAC9E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;;IAU9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAoBd,cAAc;YAmDd,eAAe;IAW7B,OAAO,CAAC,gBAAgB;CAgBzB"}
@@ -47,50 +47,46 @@ class FirebaseMcpServer {
47
47
  throw result.cause;
48
48
  this.appConfig = result.value;
49
49
  this.mcpServer.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({ tools: tools_1.allToolDefinitions }));
50
- this.mcpServer.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
51
- const name = request.params.name;
52
- const args = request.params.arguments ?? {};
53
- if (name === tools_1.GET_CONFIG) {
54
- return (0, tools_1.getConfig)(this.appConfig);
55
- }
56
- if (name === tools_1.RELOAD_CONFIG) {
57
- return (0, tools_1.reloadConfig)(async () => {
58
- const { exit: cfgExit } = (0, config_1.loadConfig)(this.configPath).fork();
59
- const cfgResult = await cfgExit;
60
- if (cfgResult._tag !== 'ok') {
61
- throw cfgResult._tag === 'err'
62
- ? cfgResult.error
63
- : cfgResult.cause;
64
- }
65
- this.projectContexts.clear();
66
- this.appConfig = cfgResult.value;
67
- return { projects: Object.keys(cfgResult.value.projects) };
68
- });
69
- }
70
- const projectId = typeof args.projectId === 'string' ? args.projectId : null;
71
- if (!projectId) {
72
- return toErrorResult('MISSING_PROJECT_ID', 'projectId is required. Call get_config to see available projects.');
73
- }
74
- const projectConfig = this.appConfig.projects[projectId];
75
- if (!projectConfig) {
76
- return toErrorResult('PROJECT_NOT_FOUND', `Project "${projectId}" not found in config. Call get_config to see available projects.`, { projectId, available: Object.keys(this.appConfig.projects) });
77
- }
78
- const { projectId: _stripped, ...toolArgs } = args;
79
- let ctx;
80
- try {
81
- ctx = await this.getOrInitProject(projectId, projectConfig);
82
- }
83
- catch (cause) {
84
- return toErrorResult('FIREBASE_INIT_ERROR', `Failed to initialize Firebase for project "${projectId}": ${String(cause)}`);
85
- }
86
- const { exit: toolExit } = (0, tools_1.dispatchTool)(ctx, name, toolArgs).fork();
87
- const toolResult = await toolExit;
88
- if (toolResult._tag === 'ok')
89
- return toolResult.value;
90
- return toErrorResult('INTERNAL_ERROR', `Unexpected error: ${String(toolResult._tag === 'err' ? toolResult.error : toolResult.cause)}`);
91
- });
50
+ this.mcpServer.server.setRequestHandler(types_js_1.CallToolRequestSchema, (request) => this.handleToolCall(request.params.name, request.params.arguments ?? {}));
92
51
  await this.mcpServer.server.connect(new stdio_js_1.StdioServerTransport());
93
52
  }
53
+ async handleToolCall(name, args) {
54
+ if (name === tools_1.GET_CONFIG)
55
+ return (0, tools_1.getConfig)(this.appConfig);
56
+ if (name === tools_1.RELOAD_CONFIG)
57
+ return (0, tools_1.reloadConfig)(() => this.reloadAppConfig());
58
+ const projectId = typeof args.projectId === 'string' ? args.projectId : null;
59
+ if (!projectId) {
60
+ return toErrorResult('MISSING_PROJECT_ID', 'projectId is required. Call get_config to see available projects.');
61
+ }
62
+ const projectConfig = this.appConfig.projects[projectId];
63
+ if (!projectConfig) {
64
+ return toErrorResult('PROJECT_NOT_FOUND', `Project "${projectId}" not found in config. Call get_config to see available projects.`, { projectId, available: Object.keys(this.appConfig.projects) });
65
+ }
66
+ const { projectId: _stripped, ...toolArgs } = args;
67
+ let ctx;
68
+ try {
69
+ ctx = await this.getOrInitProject(projectId, projectConfig);
70
+ }
71
+ catch (cause) {
72
+ return toErrorResult('FIREBASE_INIT_ERROR', `Failed to initialize Firebase for project "${projectId}": ${String(cause)}`);
73
+ }
74
+ const { exit } = (0, tools_1.dispatchTool)(ctx, name, toolArgs).fork();
75
+ const toolResult = await exit;
76
+ if (toolResult._tag === 'ok')
77
+ return toolResult.value;
78
+ return toErrorResult('INTERNAL_ERROR', `Unexpected error: ${String(toolResult._tag === 'err' ? toolResult.error : toolResult.cause)}`);
79
+ }
80
+ async reloadAppConfig() {
81
+ const { exit } = (0, config_1.loadConfig)(this.configPath).fork();
82
+ const result = await exit;
83
+ if (result._tag !== 'ok') {
84
+ throw result._tag === 'err' ? result.error : result.cause;
85
+ }
86
+ this.projectContexts.clear();
87
+ this.appConfig = result.value;
88
+ return { projects: Object.keys(result.value.projects) };
89
+ }
94
90
  getOrInitProject(projectId, config) {
95
91
  const cached = this.projectContexts.get(projectId);
96
92
  if (cached)
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/task/index.test.ts"],"names":[],"mappings":""}