@dereekb/firebase-server 13.11.18 → 13.12.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/index.cjs.js +218 -31
  2. package/index.esm.js +217 -34
  3. package/mailgun/package.json +9 -9
  4. package/mcp/index.cjs.default.js +1 -0
  5. package/mcp/index.cjs.js +3646 -0
  6. package/mcp/index.cjs.mjs +2 -0
  7. package/mcp/index.d.ts +1 -0
  8. package/mcp/index.esm.js +3609 -0
  9. package/mcp/package.json +33 -0
  10. package/mcp/src/index.d.ts +1 -0
  11. package/mcp/src/lib/controller/index.d.ts +2 -0
  12. package/mcp/src/lib/controller/mcp.controller.d.ts +19 -0
  13. package/mcp/src/lib/controller/mcp.wellknown.controller.d.ts +25 -0
  14. package/mcp/src/lib/index.d.ts +5 -0
  15. package/mcp/src/lib/mcp.config.d.ts +100 -0
  16. package/mcp/src/lib/mcp.module.d.ts +49 -0
  17. package/mcp/src/lib/service/index.d.ts +8 -0
  18. package/mcp/src/lib/service/mcp.manifest.d.ts +150 -0
  19. package/mcp/src/lib/service/mcp.response-formatter.d.ts +36 -0
  20. package/mcp/src/lib/service/mcp.server.factory.d.ts +124 -0
  21. package/mcp/src/lib/service/mcp.tool-generator.d.ts +235 -0
  22. package/mcp/src/lib/service/mcp.visibility.d.ts +99 -0
  23. package/mcp/src/lib/service/tools/mcp.tool.model-decode.d.ts +87 -0
  24. package/mcp/src/lib/service/tools/mcp.tool.model-get.d.ts +81 -0
  25. package/mcp/src/lib/service/tools/mcp.tool.model-info.d.ts +84 -0
  26. package/mcp/src/lib/service/tools/mcp.tool.whoami.d.ts +72 -0
  27. package/mcp/src/lib/transport/index.d.ts +1 -0
  28. package/mcp/src/lib/transport/streamable-http.transport.d.ts +21 -0
  29. package/model/index.cjs.js +639 -266
  30. package/model/index.esm.js +640 -270
  31. package/model/package.json +9 -9
  32. package/model/src/lib/storagefile/extension/compress.pdf.d.ts +29 -1
  33. package/model/src/lib/storagefile/index.d.ts +1 -0
  34. package/model/src/lib/storagefile/storagefile.action.server.d.ts +29 -2
  35. package/model/src/lib/storagefile/storagefile.mcp.d.ts +32 -0
  36. package/model/src/lib/storagefile/storagefile.module.d.ts +20 -3
  37. package/oidc/index.cjs.js +322 -147
  38. package/oidc/index.esm.js +321 -148
  39. package/oidc/package.json +10 -10
  40. package/oidc/src/lib/controller/oidc.wellknown.controller.d.ts +6 -15
  41. package/oidc/src/lib/middleware/oauth-auth.middleware.d.ts +22 -2
  42. package/oidc/src/lib/middleware/oauth-auth.module.d.ts +57 -0
  43. package/oidc/src/lib/oidc.config.d.ts +73 -0
  44. package/oidc/src/lib/oidc.module.d.ts +44 -2
  45. package/package.json +16 -10
  46. package/src/lib/auth/auth.service.d.ts +16 -1
  47. package/src/lib/auth/auth.service.error.util.d.ts +24 -5
  48. package/src/lib/env/env.config.d.ts +16 -0
  49. package/src/lib/env/env.service.d.ts +9 -0
  50. package/src/lib/nest/controller/model/model.api.get.service.d.ts +35 -1
  51. package/src/lib/nest/env/env.service.d.ts +1 -0
  52. package/src/lib/nest/model/api.details.d.ts +116 -5
  53. package/src/lib/nest/model/crud.assert.function.d.ts +1 -1
  54. package/src/lib/nest/model/index.d.ts +1 -0
  55. package/src/lib/nest/model/invoke.model.function.d.ts +89 -0
  56. package/test/package.json +11 -11
  57. package/twilio/LICENSE +21 -0
  58. package/twilio/index.cjs.default.js +1 -0
  59. package/twilio/index.cjs.js +404 -0
  60. package/twilio/index.cjs.mjs +2 -0
  61. package/twilio/index.d.ts +1 -0
  62. package/twilio/index.esm.js +398 -0
  63. package/twilio/package.json +25 -0
  64. package/twilio/src/index.d.ts +1 -0
  65. package/twilio/src/lib/index.d.ts +1 -0
  66. package/twilio/src/lib/notification.send.service.twilio.d.ts +148 -0
  67. package/zoho/package.json +9 -9
@@ -0,0 +1,235 @@
1
+ import { type Maybe } from '@dereekb/util';
2
+ import { type ModelApiDetailsResult, type OnCallModelFunctionApiDetails, type FirebaseServerAuthData, type McpToolDetailsBuilder } from '@dereekb/firebase-server';
3
+ import { type Request } from 'express';
4
+ import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js';
5
+ import { type McpManifestToolEntry } from './mcp.manifest';
6
+ import { type McpToolFilterMetadata } from './mcp.visibility';
7
+ /**
8
+ * Frozen wire-shape entry returned on `tools/list`.
9
+ *
10
+ * Built once at boot per tool and reused for every request when no
11
+ * {@link McpToolDefinition.toolDetailsBuilder} is configured. Tools that opt in
12
+ * to dynamic details produce a fresh wire entry per request.
13
+ */
14
+ export interface McpToolListEntry {
15
+ readonly name: string;
16
+ readonly description: string;
17
+ readonly inputSchema: object;
18
+ readonly outputSchema?: object;
19
+ }
20
+ /**
21
+ * A single MCP tool definition generated from one (modelType, callType, specifier) triple.
22
+ */
23
+ export interface McpToolDefinition {
24
+ /**
25
+ * Tool name advertised on `tools/list`.
26
+ *
27
+ * Format: `<modelType>-<callType>` for default (`_`) specifiers,
28
+ * `<modelType>-<callType>-<specifier>` for non-default specifiers.
29
+ *
30
+ * @example 'guestbook-create'
31
+ * @example 'profile-update-username'
32
+ * @example 'storageFile-invoke-recomputeChecksums'
33
+ */
34
+ readonly name: string;
35
+ /**
36
+ * Human-readable description surfaced to MCP clients.
37
+ *
38
+ * Resolved from the build-time MCP manifest entry when present; otherwise auto-generated.
39
+ */
40
+ readonly description: string;
41
+ /**
42
+ * JSON Schema for the tool input.
43
+ *
44
+ * Resolved in order: manifest entry's `inputSchema` (when a manifest is supplied) > handler's
45
+ * `inputType.toJsonSchema()` > `undefined`. `undefined` means the tool is skipped during
46
+ * registration; the gap is logged so it's visible.
47
+ */
48
+ readonly inputSchema?: object;
49
+ /**
50
+ * JSON Schema for the tool output, when the manifest provides one. The wire `tools/list`
51
+ * response only includes this when the pinned MCP SDK type allows it.
52
+ */
53
+ readonly outputSchema?: object;
54
+ /**
55
+ * The original handler-level API details. Carries response formatters, analytics
56
+ * config, etc. — the controller resolves Tier 1/2/3 response shape from this.
57
+ *
58
+ * `undefined` for statically-registered tools that don't go through the callModel chain.
59
+ */
60
+ readonly details?: OnCallModelFunctionApiDetails;
61
+ /**
62
+ * The dispatch coordinates extracted from the position in the call model tree.
63
+ * The controller uses these to build the `OnCallTypedModelParams` envelope at call time.
64
+ *
65
+ * For statically-registered tools the coordinates are synthetic (they identify the tool to
66
+ * dynamic visibility predicates) but {@link staticHandler} runs instead of the callModel chain.
67
+ */
68
+ readonly dispatch: McpToolDispatchTarget;
69
+ /**
70
+ * When present, the per-request controller calls this handler directly instead of going
71
+ * through the callModel dispatch chain. Used for built-in MCP tools (e.g. `model-get`) that
72
+ * read from the Firebase model surface without a corresponding `callModel` handler.
73
+ */
74
+ readonly staticHandler?: McpStaticToolHandler;
75
+ /**
76
+ * Precomputed boot-time filter metadata consumed by the per-request `tools/list` filter.
77
+ */
78
+ readonly filterMetadata: McpToolFilterMetadata;
79
+ /**
80
+ * The frozen `tools/list` wire entry for this tool, computed once at boot from the
81
+ * static description / inputSchema / outputSchema. The factory returns this verbatim
82
+ * when {@link toolDetailsBuilder} is `undefined`, avoiding a per-request allocation.
83
+ */
84
+ readonly staticWireEntry: McpToolListEntry;
85
+ /**
86
+ * The handler's per-request builder, hoisted from `details.mcp.toolDetails` once at
87
+ * boot so the request hot path doesn't dereference through the details tree.
88
+ *
89
+ * `undefined` for tools that did not opt in (the common case) and for statically
90
+ * registered tools.
91
+ */
92
+ readonly toolDetailsBuilder?: McpToolDetailsBuilder;
93
+ }
94
+ /**
95
+ * Per-request handler for a statically-registered MCP tool.
96
+ *
97
+ * Receives the raw tool arguments and the MCP request context (auth + raw request); returns the
98
+ * MCP `CallToolResult` envelope verbatim. The factory wraps the call in a try/catch so handlers
99
+ * may surface user-visible errors by throwing.
100
+ */
101
+ export type McpStaticToolHandler = (args: Record<string, unknown>, ctx: McpStaticToolHandlerContext) => Promise<CallToolResult>;
102
+ /**
103
+ * Request-scoped context passed to {@link McpStaticToolHandler} implementations.
104
+ *
105
+ * Identical in shape to `McpRequestContext` but redeclared here so the tool generator does not
106
+ * depend on the server factory module (the dependency goes the other way).
107
+ */
108
+ export interface McpStaticToolHandlerContext {
109
+ readonly auth?: FirebaseServerAuthData;
110
+ readonly rawRequest: Request;
111
+ }
112
+ /**
113
+ * The (call, modelType, specifier) coordinate that resolves a generated MCP tool
114
+ * back to a single dispatch target on the underlying callModel chain.
115
+ */
116
+ export interface McpToolDispatchTarget {
117
+ readonly call: string;
118
+ readonly modelType: string;
119
+ /**
120
+ * `undefined` when the handler isn't behind a specifier (default `_` entry on a
121
+ * non-specifier model type).
122
+ */
123
+ readonly specifier?: string;
124
+ }
125
+ /**
126
+ * Options forwarded to {@link JsonSchemaRef.toJsonSchema}.
127
+ *
128
+ * Wraps the ArkType-specific fallback handlers so consumers can opt out of the
129
+ * default predicate / `undefinedAsClearable` behavior if their schema lib needs
130
+ * different options.
131
+ */
132
+ export interface JsonSchemaGenerationOptions {
133
+ readonly [option: string]: unknown;
134
+ }
135
+ /**
136
+ * Default `toJsonSchema()` options.
137
+ *
138
+ * ArkType throws on predicate definitions and on `undefined` fields by default;
139
+ * these fallback handlers downgrade those errors so a partial schema is emitted
140
+ * for tools that mostly fit JSON Schema. The `unit` fallback covers `clearable(t)`
141
+ * from `@dereekb/model` (which expands to `t | undefined` and surfaces as an ArkType
142
+ * `unit: undefined` schema node).
143
+ */
144
+ export declare const DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS: JsonSchemaGenerationOptions;
145
+ /**
146
+ * Reason a tool was skipped during generation.
147
+ */
148
+ export type McpToolGenerationSkipReason = 'missing_input_type' | 'schema_generation_failed';
149
+ /**
150
+ * One tool that was skipped during generation.
151
+ */
152
+ export interface McpToolGenerationSkip {
153
+ readonly toolName: string;
154
+ readonly reason: McpToolGenerationSkipReason;
155
+ readonly dispatch: McpToolDispatchTarget;
156
+ readonly error?: Error;
157
+ }
158
+ /**
159
+ * Aggregated output of {@link generateMcpToolDefinitions}.
160
+ */
161
+ export interface McpToolGenerationResult {
162
+ /**
163
+ * Tools that may be visible on `tools/list`, subject to the per-request filter.
164
+ * Excludes anything classified as `'never'` visible at boot.
165
+ */
166
+ readonly tools: ReadonlyArray<McpToolDefinition>;
167
+ /**
168
+ * Tools whose `visibility` was classified as `'never'` at boot.
169
+ * Partitioned out so the per-request loop never touches them.
170
+ */
171
+ readonly neverVisibleTools: ReadonlyArray<McpToolDefinition>;
172
+ /**
173
+ * Tools that could not be generated (no inputType, or `toJsonSchema()` threw).
174
+ * Surfaced so the caller can log them at startup.
175
+ */
176
+ readonly skipped: ReadonlyArray<McpToolGenerationSkip>;
177
+ }
178
+ interface BuildStaticWireEntryInput {
179
+ readonly name: string;
180
+ readonly description: string;
181
+ readonly inputSchema?: object;
182
+ readonly outputSchema?: object;
183
+ }
184
+ /**
185
+ * Builds the frozen wire-shape entry used by the per-request `tools/list` hot path.
186
+ *
187
+ * Tools without an `inputSchema` default to `{ type: 'object' }` to match the runtime
188
+ * behaviour the factory used before the precompute optimisation existed.
189
+ *
190
+ * @param input - The tool name, description, and optional input/output schemas used to assemble the wire entry.
191
+ * @returns A frozen wire entry safe to share across requests.
192
+ */
193
+ export declare function buildStaticWireEntry(input: BuildStaticWireEntryInput): McpToolListEntry;
194
+ /**
195
+ * The default specifier key used when a handler is not behind a specifier router.
196
+ */
197
+ export declare const DEFAULT_SPECIFIER_KEY = "_";
198
+ /**
199
+ * Builds the MCP tool name for a (modelType, callType, specifier) triple.
200
+ *
201
+ * Apps can override the auto-generated name by setting
202
+ * {@link OnCallModelFunctionApiDetails.mcp.name} on the handler.
203
+ *
204
+ * @param modelType - The Firestore model type (e.g., `storageFile`).
205
+ * @param callType - The call type (e.g., `invoke`).
206
+ * @param specifier - The specifier key, or `_` / undefined for the default entry.
207
+ * @returns The hyphen-joined tool name advertised on `tools/list`.
208
+ */
209
+ export declare function buildMcpToolName(modelType: string, callType: string, specifier?: Maybe<string>): string;
210
+ /**
211
+ * Builds the default description used when no build-time MCP manifest
212
+ * entry is available for the (modelType, callType, specifier) tuple.
213
+ *
214
+ * @param modelType - The Firestore model type segment used in the generated description.
215
+ * @param callType - The call type segment used in the generated description.
216
+ * @param specifier - The specifier segment, or `_` / undefined for the default entry.
217
+ * @returns A human-readable fallback description for the tool.
218
+ */
219
+ export declare function buildDefaultMcpToolDescription(modelType: string, callType: string, specifier?: Maybe<string>): string;
220
+ /**
221
+ * Generates MCP tool definitions from a model-first API details tree.
222
+ *
223
+ * Walks each (modelType, callType, specifier) triple in the tree, calls
224
+ * `inputType.toJsonSchema(options)` for the schema, and applies any handler-level
225
+ * MCP `name` override. Descriptions and input/output schemas are pulled from the
226
+ * build-time manifest when supplied. Tools without an `inputType` are skipped and
227
+ * reported so callers can log the gap at startup.
228
+ *
229
+ * @param apiDetails - The model-first API details tree returned by `getModelApiDetails(callModelFn)`.
230
+ * @param options - Optional schema generation options forwarded to `toJsonSchema()`. Defaults to {@link DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS}.
231
+ * @param manifest - Optional build-time manifest map; supplies overrides for descriptions and input/output schemas keyed by {@link mcpManifestKey}.
232
+ * @returns The list of generated tool definitions plus any skip reports.
233
+ */
234
+ export declare function generateMcpToolDefinitions(apiDetails: ModelApiDetailsResult, options?: JsonSchemaGenerationOptions, manifest?: ReadonlyMap<string, McpManifestToolEntry>): McpToolGenerationResult;
235
+ export {};
@@ -0,0 +1,99 @@
1
+ import { type Maybe } from '@dereekb/util';
2
+ import { type CallModelOidcScope } from '@dereekb/firebase';
3
+ import { type McpToolVisibility, type McpVisibilityContext, type McpVisibilityRule } from '@dereekb/firebase-server';
4
+ /**
5
+ * Normalized classification of a {@link McpToolVisibility} value computed at boot.
6
+ *
7
+ * `'always'` keeps the tool (subject to scope/readOnly filters).
8
+ * `'never'` drops the tool from `tools/list` entirely — partitioned at boot so the per-request loop skips it.
9
+ * `'declarative'` carries a {@link McpVisibilityRule} checked per request without invoking user code.
10
+ * `'dynamic'` carries the original predicate; invoked per request inside try/catch.
11
+ */
12
+ export type McpToolVisibilityKind = 'always' | 'never' | 'declarative' | 'dynamic';
13
+ /**
14
+ * Boot-time classification result for one tool's `visibility` field.
15
+ *
16
+ * Discriminated by {@link McpToolVisibilityKind} so consumers can narrow `rule` /
17
+ * `visibilityFn` presence without optional-chain assertions.
18
+ */
19
+ export type ClassifiedMcpToolVisibility = ClassifiedMcpToolVisibilityAlways | ClassifiedMcpToolVisibilityNever | ClassifiedMcpToolVisibilityDeclarative | ClassifiedMcpToolVisibilityDynamic;
20
+ export interface ClassifiedMcpToolVisibilityAlways {
21
+ readonly visibilityKind: 'always';
22
+ }
23
+ export interface ClassifiedMcpToolVisibilityNever {
24
+ readonly visibilityKind: 'never';
25
+ }
26
+ export interface ClassifiedMcpToolVisibilityDeclarative {
27
+ readonly visibilityKind: 'declarative';
28
+ readonly rule: McpVisibilityRule;
29
+ }
30
+ export interface ClassifiedMcpToolVisibilityDynamic {
31
+ readonly visibilityKind: 'dynamic';
32
+ readonly visibilityFn: (context: McpVisibilityContext) => boolean;
33
+ }
34
+ /**
35
+ * Per-tool boot-time filter metadata. The per-request loop reads these fields directly.
36
+ *
37
+ * Discriminated by {@link McpToolVisibilityKind} so the request loop narrows to the
38
+ * exact variant carrying `rule` or `visibilityFn` without optional-chain assertions.
39
+ */
40
+ export type McpToolFilterMetadata = McpToolFilterMetadataAlways | McpToolFilterMetadataNever | McpToolFilterMetadataDeclarative | McpToolFilterMetadataDynamic;
41
+ interface McpToolFilterMetadataBase {
42
+ /**
43
+ * OIDC scope required to invoke this tool. Precomputed from the dispatch call type.
44
+ * `undefined` for non-CRUD call types (apps gate those via their own preAssert if needed).
45
+ */
46
+ readonly requiredScope?: CallModelOidcScope;
47
+ /**
48
+ * Effective read-only classification used by the module-level `readOnly` filter.
49
+ *
50
+ * Explicit handler `mcp.readOnly` wins. Otherwise inferred from the call type:
51
+ * `read`/`query` → true; `create`/`update`/`delete` → false; anything else → undefined.
52
+ * Unknown counts as a write for fail-safe filtering.
53
+ */
54
+ readonly effectiveReadOnly?: boolean;
55
+ }
56
+ export interface McpToolFilterMetadataAlways extends McpToolFilterMetadataBase {
57
+ readonly visibilityKind: 'always';
58
+ }
59
+ export interface McpToolFilterMetadataNever extends McpToolFilterMetadataBase {
60
+ readonly visibilityKind: 'never';
61
+ }
62
+ export interface McpToolFilterMetadataDeclarative extends McpToolFilterMetadataBase {
63
+ readonly visibilityKind: 'declarative';
64
+ readonly rule: McpVisibilityRule;
65
+ }
66
+ export interface McpToolFilterMetadataDynamic extends McpToolFilterMetadataBase {
67
+ readonly visibilityKind: 'dynamic';
68
+ readonly visibilityFn: (context: McpVisibilityContext) => boolean;
69
+ }
70
+ /**
71
+ * Classifies a {@link McpToolVisibility} value into its normalized boot-time form.
72
+ *
73
+ * Defaults `undefined` to `'always'` so handlers without a visibility field stay visible.
74
+ *
75
+ * @param visibility - The raw visibility value from the handler's `mcp.visibility` field.
76
+ * @returns The discriminated classification used by the per-request filter loop.
77
+ */
78
+ export declare function classifyVisibility(visibility?: McpToolVisibility): ClassifiedMcpToolVisibility;
79
+ /**
80
+ * Resolves the effective read-only classification for a handler.
81
+ *
82
+ * Explicit handler override wins. Otherwise infers from the call type. Returns
83
+ * `undefined` when neither source provides a definite classification.
84
+ *
85
+ * @param explicitReadOnly - The handler's explicit `mcp.readOnly` value, if any.
86
+ * @param callType - The dispatch call type used to infer read-only when no override is present.
87
+ * @returns The effective read-only flag, or `undefined` when neither source resolves a value.
88
+ */
89
+ export declare function resolveEffectiveReadOnly(explicitReadOnly: Maybe<boolean>, callType: string): boolean | undefined;
90
+ /**
91
+ * Resolves the OIDC scope required to invoke a given call type, or `undefined` for
92
+ * non-CRUD calls. Thin re-export so the tool generator doesn't need to reach into
93
+ * `@dereekb/firebase` directly.
94
+ *
95
+ * @param callType - The dispatch call type to map to a CRUD OIDC scope.
96
+ * @returns The required scope for this call type, or `undefined` when no scope is enforced.
97
+ */
98
+ export declare function resolveRequiredScope(callType: string): Maybe<CallModelOidcScope>;
99
+ export {};
@@ -0,0 +1,87 @@
1
+ import { type McpManifestModelEntry } from '../mcp.manifest';
2
+ import { type McpToolDefinition } from '../mcp.tool-generator';
3
+ /**
4
+ * Reserved tool name for the built-in `model-decode` static tool.
5
+ */
6
+ export declare const MODEL_DECODE_TOOL_NAME = "model-decode";
7
+ /**
8
+ * Synthetic call type used in the tool's dispatch identity. Aligns with the dbx-cli `model-decode`
9
+ * command.
10
+ */
11
+ export declare const MODEL_DECODE_DISPATCH_CALL = "decode";
12
+ /**
13
+ * Synthetic model type used in the tool's dispatch identity. Mirrors the other built-in static
14
+ * tools (`model-get`, `model-info`); apps avoiding collisions should not register a real model
15
+ * literally named "model".
16
+ */
17
+ export declare const MODEL_DECODE_DISPATCH_MODEL_TYPE = "model";
18
+ /**
19
+ * Constructor dependencies for {@link createModelDecodeTool}.
20
+ */
21
+ export interface CreateModelDecodeToolDeps {
22
+ /**
23
+ * Frozen catalog of Firestore models used to resolve segment prefixes.
24
+ */
25
+ readonly manifest: readonly McpManifestModelEntry[];
26
+ }
27
+ /**
28
+ * Shape of the `model-decode` tool input.
29
+ */
30
+ export interface ModelDecodeToolInput {
31
+ readonly key: string;
32
+ }
33
+ /**
34
+ * One segment of a decoded Firestore key. `model*` fields are absent when the
35
+ * segment's `prefix` isn't in the manifest.
36
+ */
37
+ export interface DecodedKeySegment {
38
+ readonly prefix: string;
39
+ readonly id: string;
40
+ readonly modelType?: string;
41
+ readonly modelName?: string;
42
+ readonly modelGroup?: string;
43
+ readonly identityConst?: string;
44
+ readonly parentIdentityConst?: string;
45
+ readonly sourcePackage?: string;
46
+ readonly sourceFile?: string;
47
+ }
48
+ /**
49
+ * Output payload for the `model-decode` tool.
50
+ */
51
+ export interface ModelDecodeToolOutput {
52
+ readonly key: string;
53
+ readonly leaf: DecodedKeySegment;
54
+ readonly ancestors: ReadonlyArray<DecodedKeySegment>;
55
+ readonly unresolvedPrefixes: ReadonlyArray<string>;
56
+ }
57
+ /**
58
+ * Builds the built-in `model-decode` MCP tool definition.
59
+ *
60
+ * Mirrors dbx-cli's `model-decode <key>` command:
61
+ * - Splits the supplied Firestore key on `/`, walks `[prefix, id]` pairs, and resolves each prefix
62
+ * against the manifest.
63
+ * - Supports subcollection paths (`parentPrefix/parentId/childPrefix/childId`).
64
+ *
65
+ * Output is delivered as both stringified JSON in `content[0].text` and `structuredContent` so
66
+ * MCP clients can consume either form.
67
+ *
68
+ * @param deps - The frozen model manifest loaded at boot from the MCP manifest JSON.
69
+ * @returns A statically-registered {@link McpToolDefinition} ready to be appended to the MCP
70
+ * server factory's tool registry.
71
+ */
72
+ export declare function createModelDecodeTool(deps: CreateModelDecodeToolDeps): McpToolDefinition;
73
+ /**
74
+ * Splits `rawKey` on `/`, resolves each `[prefix, id]` pair against the manifest, and
75
+ * returns the leaf segment + ancestor chain.
76
+ *
77
+ * Mirrors the dbx-cli `decodeFirestoreModelKey` helper structurally; both implementations
78
+ * must stay in lockstep on segment count and resolution order.
79
+ *
80
+ * @param rawKey - The Firestore key string.
81
+ * @param manifest - The model manifest.
82
+ * @returns The decoded key with leaf, ancestors, and any unresolved prefixes.
83
+ * @throws {Error} When `rawKey` is empty or does not parse into an even number of `prefix/id` segments.
84
+ *
85
+ * @__NO_SIDE_EFFECTS__
86
+ */
87
+ export declare function decodeFirestoreModelKey(rawKey: string, manifest: ReadonlyArray<McpManifestModelEntry>): ModelDecodeToolOutput;
@@ -0,0 +1,81 @@
1
+ import { type Maybe } from '@dereekb/util';
2
+ import { type FirestoreModelIdentity, type FirestoreModelKey, type FirestoreModelType } from '@dereekb/firebase';
3
+ import { type ModelAccessMultiReadResult, type FirebaseServerAuthData } from '@dereekb/firebase-server';
4
+ import { type McpToolDefinition } from '../mcp.tool-generator';
5
+ /**
6
+ * Reserved tool name for the built-in `model-get` static tool.
7
+ */
8
+ export declare const MODEL_GET_TOOL_NAME = "model-get";
9
+ /**
10
+ * Synthetic call type used in the tool's dispatch identity. Aligns with the dbx-cli `get`
11
+ * command and the `/api/model/:modelType/get` HTTP endpoint that backs it.
12
+ */
13
+ export declare const MODEL_GET_DISPATCH_CALL = "get";
14
+ /**
15
+ * Synthetic model type used in the tool's dispatch identity. The tool itself isn't bound to a
16
+ * specific model type (the `modelType` is part of its input), so we use the literal "model" as
17
+ * the identity. Apps avoiding collision should not register a real model literally named
18
+ * "model".
19
+ */
20
+ export declare const MODEL_GET_DISPATCH_MODEL_TYPE = "model";
21
+ /**
22
+ * Maximum number of keys per backend multi-read request. Matches
23
+ * `MAX_MODEL_ACCESS_MULTI_READ_KEYS` exported from `@dereekb/firebase-server`; mirrored as a
24
+ * local constant so the bundler doesn't have to follow the import chain just for one number.
25
+ */
26
+ export declare const MCP_MODEL_GET_BATCH_SIZE = 50;
27
+ /**
28
+ * Per-batch read function. Identical signature to {@link ModelApiGetService.readDocuments} so the
29
+ * service method can be passed directly.
30
+ */
31
+ export type McpModelGetReadDocuments = (modelType: FirestoreModelType, keys: FirestoreModelKey[], auth: Maybe<FirebaseServerAuthData>) => Promise<ModelAccessMultiReadResult>;
32
+ /**
33
+ * Lookup function that resolves a `modelType` to its registered {@link FirestoreModelIdentity}.
34
+ *
35
+ * Takes the request's auth so the wiring layer can build a real model context on first use
36
+ * (the underlying `getFirestoreCollection(context)` accessor is context-dependent). Returns
37
+ * `undefined` for unknown model types; the handler surfaces this as a user-visible error.
38
+ */
39
+ export type McpModelGetResolveIdentity = (modelType: FirestoreModelType, auth: Maybe<FirebaseServerAuthData>) => Maybe<FirestoreModelIdentity>;
40
+ /**
41
+ * Constructor dependencies for {@link createModelGetTool}.
42
+ */
43
+ export interface CreateModelGetToolDeps {
44
+ /**
45
+ * Reads a batch of model documents. Provided as a callback so the unit tests can mock it
46
+ * without instantiating the Nest DI container.
47
+ */
48
+ readonly readDocuments: McpModelGetReadDocuments;
49
+ /**
50
+ * Resolves the registered identity for a model type so bare ids can be promoted into full
51
+ * `prefix/id` keys.
52
+ */
53
+ readonly resolveIdentity: McpModelGetResolveIdentity;
54
+ }
55
+ /**
56
+ * Shape of the `model-get` tool input.
57
+ */
58
+ export interface ModelGetToolInput {
59
+ readonly modelType: string;
60
+ readonly keys: ReadonlyArray<string>;
61
+ }
62
+ /**
63
+ * Builds the built-in `model-get` MCP tool definition.
64
+ *
65
+ * Mirrors dbx-cli's `get` / `get-many` behavior:
66
+ * - Accepts an array of keys; values containing `/` are treated as full keys and passed verbatim
67
+ * while bare ids are promoted to `${collectionName}/${id}` for root models.
68
+ * - Nested (subcollection) models reject bare ids since a parent path is required.
69
+ * - Auto-chunks at {@link MCP_MODEL_GET_BATCH_SIZE} keys per backend call, mirroring
70
+ * `getMultipleModelsOverHttpChunked` on the CLI side.
71
+ *
72
+ * The handler returns the same `{ results, errors }` shape produced by
73
+ * `ModelApiGetService.readDocuments`, exposed via both the text content block and
74
+ * `structuredContent` so MCP clients can consume either form.
75
+ *
76
+ * @param deps - Read-documents and identity-resolver callbacks (typically wired to
77
+ * `ModelApiGetService`).
78
+ * @returns A statically-registered {@link McpToolDefinition} ready to be appended to the MCP
79
+ * server factory's tool registry.
80
+ */
81
+ export declare function createModelGetTool(deps: CreateModelGetToolDeps): McpToolDefinition;
@@ -0,0 +1,84 @@
1
+ import { type McpManifestModelEntry } from '../mcp.manifest';
2
+ import { type McpToolDefinition } from '../mcp.tool-generator';
3
+ /**
4
+ * Reserved tool name for the built-in `model-info` static tool.
5
+ */
6
+ export declare const MODEL_INFO_TOOL_NAME = "model-info";
7
+ /**
8
+ * Synthetic call type used in the tool's dispatch identity. Aligns with the dbx-cli `model-info`
9
+ * command.
10
+ */
11
+ export declare const MODEL_INFO_DISPATCH_CALL = "info";
12
+ /**
13
+ * Synthetic model type used in the tool's dispatch identity. Mirrors {@link MODEL_GET_DISPATCH_MODEL_TYPE};
14
+ * apps avoiding collisions should not register a real model literally named "model".
15
+ */
16
+ export declare const MODEL_INFO_DISPATCH_MODEL_TYPE = "model";
17
+ /**
18
+ * Constructor dependencies for {@link createModelInfoTool}.
19
+ */
20
+ export interface CreateModelInfoToolDeps {
21
+ /**
22
+ * Frozen catalog of Firestore models exposed by the host app, sourced from the build-time
23
+ * manifest JSON.
24
+ */
25
+ readonly manifest: readonly McpManifestModelEntry[];
26
+ }
27
+ /**
28
+ * Shape of the `model-info` tool input. Omit `model` to list every model in the manifest.
29
+ */
30
+ export interface ModelInfoToolInput {
31
+ readonly model?: string;
32
+ }
33
+ /**
34
+ * Summary row returned in list mode.
35
+ */
36
+ export interface ModelInfoSummaryRow {
37
+ readonly modelType: string;
38
+ readonly modelName: string;
39
+ readonly modelGroup?: string;
40
+ readonly identityConst: string;
41
+ readonly collectionPrefix: string;
42
+ readonly parentIdentityConst?: string;
43
+ readonly sourcePackage: string;
44
+ readonly fieldCount: number;
45
+ readonly description?: string;
46
+ readonly read?: 'system' | 'owner' | 'admin-only' | 'permissions';
47
+ readonly serviceFactoryExport?: string;
48
+ }
49
+ /**
50
+ * Output payload for the `model-info` tool. `mode === 'list'` carries `models[]`;
51
+ * `mode === 'single'` carries the full `model` entry.
52
+ */
53
+ export type ModelInfoToolOutput = {
54
+ readonly mode: 'list';
55
+ readonly models: ReadonlyArray<ModelInfoSummaryRow>;
56
+ } | {
57
+ readonly mode: 'single';
58
+ readonly model: McpManifestModelEntry;
59
+ };
60
+ /**
61
+ * Builds the built-in `model-info` MCP tool definition.
62
+ *
63
+ * Mirrors dbx-cli's `model-info [model]` command:
64
+ * - Without a `model` arg: returns a summary list (modelType, modelName, prefix, group, identity, field count).
65
+ * - With a `model` arg: matches by `modelType`, `identityConst`, or `collectionPrefix` and returns the full entry.
66
+ *
67
+ * Output is delivered as both stringified JSON in `content[0].text` and `structuredContent`
68
+ * so MCP clients can consume either form.
69
+ *
70
+ * @param deps - The frozen model manifest loaded at boot from the MCP manifest JSON.
71
+ * @returns A statically-registered {@link McpToolDefinition} ready to be appended to the MCP
72
+ * server factory's tool registry.
73
+ */
74
+ export declare function createModelInfoTool(deps: CreateModelInfoToolDeps): McpToolDefinition;
75
+ /**
76
+ * Resolves a manifest entry by `modelType`, `identityConst`, or `collectionPrefix`.
77
+ *
78
+ * @param query - Identifier to look up.
79
+ * @param manifest - Model manifest to search.
80
+ * @returns The matching entry or `undefined`.
81
+ *
82
+ * @__NO_SIDE_EFFECTS__
83
+ */
84
+ export declare function findModelEntry(query: string, manifest: ReadonlyArray<McpManifestModelEntry>): McpManifestModelEntry | undefined;
@@ -0,0 +1,72 @@
1
+ import { type McpAuthRoleReader } from '../../mcp.config';
2
+ import { type McpManifestAuth } from '../mcp.manifest';
3
+ import { type McpToolDefinition } from '../mcp.tool-generator';
4
+ /**
5
+ * Reserved tool name for the built-in `whoami` static tool.
6
+ */
7
+ export declare const WHOAMI_TOOL_NAME = "whoami";
8
+ /**
9
+ * Synthetic call type used in the tool's dispatch identity. Matches the
10
+ * pattern set by `model-info` — `read` (not `info`) so the visibility
11
+ * classifier treats the tool as a read.
12
+ */
13
+ export declare const WHOAMI_DISPATCH_CALL = "read";
14
+ /**
15
+ * Synthetic model type used in the tool's dispatch identity.
16
+ */
17
+ export declare const WHOAMI_DISPATCH_MODEL_TYPE = "auth";
18
+ /**
19
+ * Constructor dependencies for {@link createWhoamiTool}.
20
+ */
21
+ export interface CreateWhoamiToolDeps {
22
+ /**
23
+ * Auth section loaded from the pre-rendered MCP manifest JSON. Drives the
24
+ * description text plus the role-detail enrichment for claim keys present
25
+ * on the live token.
26
+ */
27
+ readonly auth: McpManifestAuth;
28
+ /**
29
+ * Optional role reader. When present, decodes the live token's claims into
30
+ * a {@link AuthRoleSet}; the resulting roles are returned alongside the
31
+ * claim details. When absent, `roles` is empty.
32
+ */
33
+ readonly roleReader?: McpAuthRoleReader;
34
+ }
35
+ /**
36
+ * One entry returned in `claimDetails`. Mirrors the `dbx_auth_list_app`
37
+ * formatter shape minus source paths.
38
+ */
39
+ export interface WhoamiClaimDetail {
40
+ readonly key: string;
41
+ readonly interfaceName?: string;
42
+ readonly description: string;
43
+ readonly grantedRoles: readonly string[];
44
+ readonly inverse: boolean;
45
+ readonly tags: readonly string[];
46
+ }
47
+ /**
48
+ * Output payload for the `whoami` tool.
49
+ */
50
+ export interface WhoamiToolOutput {
51
+ readonly authenticated: boolean;
52
+ readonly uid?: string;
53
+ readonly email?: string;
54
+ readonly emailVerified?: boolean;
55
+ readonly app?: string;
56
+ readonly claims: Readonly<Record<string, unknown>>;
57
+ readonly roles: readonly string[];
58
+ readonly claimDetails: readonly WhoamiClaimDetail[];
59
+ readonly unknownClaimKeys: readonly string[];
60
+ }
61
+ /**
62
+ * Builds the built-in `whoami` MCP tool definition. Returns the calling
63
+ * caller's `uid`, claims object, decoded role set, and rendered descriptions
64
+ * for every claim key actually present on the live token.
65
+ *
66
+ * Unauthenticated callers receive a structured `authenticated: false` result
67
+ * (no exception) so the tool can be used as a "do you see me?" probe.
68
+ *
69
+ * @param deps - The manifest's auth section + optional role reader.
70
+ * @returns A statically-registered {@link McpToolDefinition} to append to the MCP server factory's tool registry.
71
+ */
72
+ export declare function createWhoamiTool(deps: CreateWhoamiToolDeps): McpToolDefinition;
@@ -0,0 +1 @@
1
+ export * from './streamable-http.transport';