@mongrov/analytics 0.1.0-alpha.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Mongrov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -289,20 +289,40 @@ fake.failExecuteMatching(/^DELETE FROM /, new Error('retention sad'))
289
289
  **Fake KV** — in-memory `KVStore` implementation with the backing map
290
290
  exposed for direct assertions.
291
291
 
292
- ## Integration testing (T-18 pending)
292
+ ## Integration testing (live MinIO + Iceberg REST)
293
293
 
294
- Full end-to-end coverage against a real MinIO + Iceberg REST catalog is
295
- planned for T-18 in Phase 8. The intended shape:
294
+ The `test:integration` script drives the shipped `createAnalytics()`
295
+ factory against a real docker-compose stack (MinIO + Tabular's
296
+ `iceberg-rest`). Six scenarios cover the T-18 (analytics-core) and
297
+ T-28 (analytics-sync) acceptance criteria:
296
298
 
297
- 1. Boot MinIO + Iceberg REST via testcontainers.
298
- 2. `createAnalytics` with a real `duckdbFactory` and pointing at the test
299
- endpoint.
300
- 3. `attach INSERT (via appender) SELECT detach reattach` assert
301
- no leakage.
302
- 4. Brand-switch scenario: attach `brandA`, detach, attach `brandB`, confirm
303
- no cross-brand catalog visibility.
299
+ | Suite | Cases |
300
+ |---|---|
301
+ | `src/core/__tests__/minio.integration.test.ts` | attach round-trip, reattach preserves rows, catalog-alias isolation, retention sweep respects watermark, token refresh at 75 % TTL |
302
+ | `src/sync/__tests__/push-fetch.integration.test.ts` | push localfetch back into fresh engine, byte-equal round trip |
303
+
304
+ ```bash
305
+ # One-shot (boots + tears down docker):
306
+ pnpm test:integration
307
+
308
+ # Iterative loop (keep the stack up between runs):
309
+ cd infra/analytics-minio && docker compose up -d --wait && cd ../..
310
+ INTEGRATION_STACK_EXTERNAL=1 pnpm test:integration
311
+ ```
312
+
313
+ Details in
314
+ [`infra/analytics-minio/README.md`](./infra/analytics-minio/README.md)
315
+ (compose recipe, credentials, port map, image pins) and
316
+ [`src/__integration__/README.md`](./src/__integration__/README.md)
317
+ (harness architecture, divergences from prod, how to add a case).
304
318
 
305
- This suite is deferred until testcontainers infra lands.
319
+ **CI**: the top-level workflow runs the fast unit matrix and a
320
+ dedicated `analytics-integration` job that boots the compose stack in
321
+ docker. See `.github/workflows/ci.yml`.
322
+
323
+ `@duckdb/node-api` is a **devDependency** — it never enters the
324
+ shipped bundle. React Native consumers still ship
325
+ `react-native-duckdb` via the app-level `duckdbFactory`.
306
326
 
307
327
  ## Boundaries
308
328
 
@@ -451,6 +471,22 @@ Fixture exports used across mapper + firmware tests live at
451
471
  Consumers writing their own regression tests can import them via a relative
452
472
  path inside this workspace; they are excluded from the published `dist/`.
453
473
 
474
+ ## AI tools (`@mongrov/analytics/tools`)
475
+
476
+ Six read-only AI SDK v4 tools (`getHRV`, `getSleepSummary`,
477
+ `getActivityTotal`, `compareTrend`, `detectAnomaly`, `getInsights`)
478
+ sit on top of the warehouse, wired through a
479
+ `rate → auth → execute → budget → audit` chain. See
480
+ [`src/tools/README.md`](./src/tools/README.md).
481
+
482
+ ### MCP dev server (`@mongrov/analytics/tools/mcp`)
483
+
484
+ Same six tools, exposed over Model Context Protocol via stdio
485
+ (Claude Desktop) or HTTP with bearer auth (MCP Inspector, curl).
486
+ Dev-guarded (`shouldStartMcpServer()`) + `sideEffects: false` so
487
+ prod RN bundles drop the SDK. See
488
+ [`src/tools/mcp/README.md`](./src/tools/mcp/README.md).
489
+
454
490
  ## License
455
491
 
456
492
  MIT
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/core/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,UAAU,CAAA;AAe7D,OAAO,KAAK,EAEV,eAAe,EACf,eAAe,EAIhB,MAAM,SAAS,CAAA;AA6BhB;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAoCD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,QAAQ,GAAE,uBAA4B,GACrC,eAAe,CA2LjB"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/core/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,UAAU,CAAA;AAe7D,OAAO,KAAK,EAEV,eAAe,EACf,eAAe,EAIhB,MAAM,SAAS,CAAA;AA6BhB;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAoCD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,QAAQ,GAAE,uBAA4B,GACrC,eAAe,CAqNjB"}
@@ -138,8 +138,34 @@ export function createAnalytics(config, internal = {}) {
138
138
  return;
139
139
  await runRetentionSweep(db, catalog, { effectiveDays });
140
140
  }
141
+ /**
142
+ * Await a state that permits an ATTACH transition. `createAnalytics` starts
143
+ * the actor + sends OPEN synchronously; consumers that call `attach()`
144
+ * immediately race the `opening → ready` transition. xstate drops events
145
+ * from disallowed states, so without this guard the pending
146
+ * `waitForNextState('attached'|'error')` would never resolve.
147
+ *
148
+ * Polls instead of `waitForNextState` to sidestep the race between reading
149
+ * `currentState()` and installing the subscription: xstate can transition
150
+ * between the two calls, at which point `waitForNextState`'s skip-first
151
+ * logic swallows the transition we care about and blocks forever.
152
+ */
153
+ async function ensureReadyForAttach() {
154
+ for (let i = 0; i < 1000; i++) { // ~10s cap
155
+ const s = currentState(actor);
156
+ if (s === 'ready' || s === 'attached')
157
+ return;
158
+ if (s === 'error') {
159
+ throw actor.getSnapshot().context.lastError
160
+ ?? new AnalyticsError('engine_open_failed', 'engine transitioned to error before ready');
161
+ }
162
+ await new Promise(resolve => setTimeout(resolve, 10));
163
+ }
164
+ throw new AnalyticsError('engine_open_failed', 'engine never reached ready state within timeout');
165
+ }
141
166
  const engine = {
142
167
  async attach(ctx) {
168
+ await ensureReadyForAttach();
143
169
  const pending = waitForNextState(actor, ['attached', 'error']);
144
170
  actor.send({ type: 'ATTACH', ctx });
145
171
  const final = await pending;
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/core/factory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/core/factory.ts"],"names":[],"mappings":"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"}
@@ -39,11 +39,11 @@ export const SCHEMAS = Object.freeze({
39
39
  family_id VARCHAR NOT NULL,
40
40
  user_id VARCHAR NOT NULL,
41
41
  device_id VARCHAR NOT NULL,
42
- hrv_ms SMALLINT,
43
- stress SMALLINT,
44
- systolic_bp SMALLINT,
45
- diastolic_bp SMALLINT,
46
- vascular_aging SMALLINT
42
+ hrv_ms INTEGER,
43
+ stress INTEGER,
44
+ systolic_bp INTEGER,
45
+ diastolic_bp INTEGER,
46
+ vascular_aging INTEGER
47
47
  ) PARTITIONED BY (day(ts), user_id);`,
48
48
  heart_rate: `CREATE TABLE heart_rate (
49
49
  ts TIMESTAMP NOT NULL,
@@ -51,7 +51,7 @@ export const SCHEMAS = Object.freeze({
51
51
  family_id VARCHAR NOT NULL,
52
52
  user_id VARCHAR NOT NULL,
53
53
  device_id VARCHAR NOT NULL,
54
- bpm SMALLINT NOT NULL
54
+ bpm INTEGER NOT NULL
55
55
  ) PARTITIONED BY (day(ts), user_id);`,
56
56
  spo2: `CREATE TABLE spo2 (
57
57
  ts TIMESTAMP NOT NULL,
@@ -59,7 +59,7 @@ export const SCHEMAS = Object.freeze({
59
59
  family_id VARCHAR NOT NULL,
60
60
  user_id VARCHAR NOT NULL,
61
61
  device_id VARCHAR NOT NULL,
62
- spo2 SMALLINT NOT NULL
62
+ spo2 INTEGER NOT NULL
63
63
  ) PARTITIONED BY (day(ts), user_id);`,
64
64
  temperature: `CREATE TABLE temperature (
65
65
  ts TIMESTAMP NOT NULL,
@@ -67,7 +67,7 @@ export const SCHEMAS = Object.freeze({
67
67
  family_id VARCHAR NOT NULL,
68
68
  user_id VARCHAR NOT NULL,
69
69
  device_id VARCHAR NOT NULL,
70
- temp_c SMALLINT NOT NULL
70
+ temp_c INTEGER NOT NULL
71
71
  ) PARTITIONED BY (day(ts), user_id);`,
72
72
  activity: `CREATE TABLE activity (
73
73
  ts TIMESTAMP NOT NULL,
@@ -109,7 +109,7 @@ export const SCHEMAS = Object.freeze({
109
109
  family_id VARCHAR NOT NULL,
110
110
  user_id VARCHAR NOT NULL,
111
111
  device_id VARCHAR NOT NULL,
112
- stage SMALLINT NOT NULL,
112
+ stage INTEGER NOT NULL,
113
113
  confidence DOUBLE
114
114
  ) PARTITIONED BY (day(ts), user_id);`,
115
115
  sleep_raw: `CREATE TABLE sleep_raw (
@@ -119,8 +119,8 @@ export const SCHEMAS = Object.freeze({
119
119
  family_id VARCHAR NOT NULL,
120
120
  user_id VARCHAR NOT NULL,
121
121
  device_id VARCHAR NOT NULL,
122
- quality SMALLINT NOT NULL,
123
- unit_length SMALLINT
122
+ quality INTEGER NOT NULL,
123
+ unit_length INTEGER
124
124
  ) PARTITIONED BY (day(ts_session_start), user_id);`,
125
125
  device_event: `CREATE TABLE device_event (
126
126
  ts TIMESTAMP NOT NULL,
@@ -129,18 +129,18 @@ export const SCHEMAS = Object.freeze({
129
129
  user_id VARCHAR NOT NULL,
130
130
  device_id VARCHAR NOT NULL,
131
131
  event_type VARCHAR NOT NULL,
132
- payload JSON
132
+ payload VARCHAR
133
133
  ) PARTITIONED BY (day(ts));`,
134
134
  device_config: `CREATE TABLE device_config (
135
135
  device_id VARCHAR NOT NULL,
136
136
  brand VARCHAR NOT NULL,
137
137
  family_id VARCHAR NOT NULL,
138
138
  user_id VARCHAR NOT NULL,
139
- data_type SMALLINT NOT NULL,
140
- interval_minutes SMALLINT NOT NULL,
139
+ data_type INTEGER NOT NULL,
140
+ interval_minutes INTEGER NOT NULL,
141
141
  start_time VARCHAR,
142
142
  end_time VARCHAR,
143
- weeks SMALLINT,
143
+ weeks INTEGER,
144
144
  valid_from TIMESTAMP NOT NULL,
145
145
  valid_to TIMESTAMP,
146
146
  PRIMARY KEY (device_id, data_type, valid_from)
@@ -155,7 +155,7 @@ export const SCHEMAS = Object.freeze({
155
155
  severity VARCHAR NOT NULL,
156
156
  title VARCHAR NOT NULL,
157
157
  body TEXT,
158
- evidence JSON,
158
+ evidence VARCHAR,
159
159
  acknowledged_at TIMESTAMP
160
160
  ) PARTITIONED BY (day(ts));`,
161
161
  sync_watermark: `CREATE TABLE sync_watermark (
@@ -168,12 +168,12 @@ export const SCHEMAS = Object.freeze({
168
168
  PRIMARY KEY (brand, family_id, table_name, kind)
169
169
  );`,
170
170
  tool_call_audit: `CREATE TABLE tool_call_audit (
171
- ts TIMESTAMP NOT NULL DEFAULT now(),
171
+ ts TIMESTAMP NOT NULL,
172
172
  brand VARCHAR NOT NULL,
173
173
  family_id VARCHAR NOT NULL,
174
174
  requester_user_id VARCHAR NOT NULL,
175
175
  tool_name VARCHAR NOT NULL,
176
- args JSON NOT NULL,
176
+ args VARCHAR NOT NULL,
177
177
  result_bytes INTEGER,
178
178
  result_row_count INTEGER,
179
179
  latency_ms INTEGER,
@@ -1 +1 @@
1
- {"version":3,"file":"warehouse.d.ts","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,WAAW,EAEX,WAAW,EACZ,MAAM,SAAS,CAAA;AAchB,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,mBAAmB,EAAE,CACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,KACb,MAAM,CAAA;IACX,WAAW,EAAE,WAAW,CAAA;IACxB,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,eAAe,EAAE,MAAM,CAAA;IACvB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,cAAc,EAAE,IAAI,CAAA;IACpB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,CAAC,CAsFvB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAaf"}
1
+ {"version":3,"file":"warehouse.d.ts","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,WAAW,EAEX,WAAW,EACZ,MAAM,SAAS,CAAA;AAchB,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,mBAAmB,EAAE,CACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,KACb,MAAM,CAAA;IACX,WAAW,EAAE,WAAW,CAAA;IACxB,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,eAAe,EAAE,MAAM,CAAA;IACvB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,cAAc,EAAE,IAAI,CAAA;IACpB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,CAAC,CA8FvB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAiBf"}
@@ -71,9 +71,17 @@ export async function attachWarehouse(db, ctx, deps) {
71
71
  catch (cause) {
72
72
  throw new AnalyticsError('attach_failed', `CREATE SECRET failed for ${secretName}`, rootCause(cause));
73
73
  }
74
- // Step 4: ATTACH
74
+ // Step 4: ATTACH + pin the current schema to the `default` namespace.
75
+ //
76
+ // DuckDB's Iceberg attach does not select a namespace, so unqualified
77
+ // `<catalog>.<table>` DDL (see `schemas.ts` / `qualifyDdl`) would resolve
78
+ // against schema `""` and fail with `Schema with name "" not found`.
79
+ // Iceberg mandates 3-part names; picking `default` here lets the rest of
80
+ // the codebase keep the 2-part `<catalog>.<table>` shape it was written
81
+ // against. Callers that need a different namespace should attach directly.
75
82
  try {
76
83
  await db.execute(`ATTACH '${uri}' AS ${secretName} (TYPE ICEBERG);`);
84
+ await db.execute(`USE ${secretName}.default;`);
77
85
  }
78
86
  catch (cause) {
79
87
  throw new AnalyticsError('attach_failed', `ATTACH failed for ${secretName}`, rootCause(cause));
@@ -106,6 +114,10 @@ export async function attachWarehouse(db, ctx, deps) {
106
114
  export async function detachWarehouse(db, tenantId) {
107
115
  const secretName = warehouseSecretName(tenantId);
108
116
  try {
117
+ // DuckDB refuses to detach the current default database, and `attach`
118
+ // above pinned it to `${secretName}.default`. Reset to the in-memory
119
+ // catalog before detaching so DETACH succeeds.
120
+ await db.execute(`USE memory.main;`);
109
121
  await db.execute(`DETACH ${secretName};`);
110
122
  await db.execute(`DROP SECRET ${secretName};`);
111
123
  }
@@ -1 +1 @@
1
- {"version":3,"file":"warehouse.js","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"warehouse.js","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * `toMcpTools` — adapt the six wrapped AI SDK v4 tools that back
3
+ * `AnalyticsToolsHandle` into the shape MCP servers speak.
4
+ *
5
+ * MCP servers want `{ name, description, inputSchema (JSON Schema),
6
+ * handler(args) => { content: [{ type: 'text', text }] } }`. Our
7
+ * factory returns AI SDK v4 tools whose `execute(args, opts) =>
8
+ * Promise<string>` already runs the full
9
+ * rate → auth → execute → budget → audit chain — so the adapter is
10
+ * a thin translation layer, not a second wrapper.
11
+ *
12
+ * The Zod parameter schemas are converted to JSON Schema draft-7 via
13
+ * `zod-to-json-schema` (drops `$schema` and `additionalProperties`
14
+ * so MCP clients get a compact tool descriptor). `.default()` values
15
+ * survive the conversion (asserted in the tests) so LLMs see the
16
+ * documented defaults on `detectAnomaly.stddevThreshold` and
17
+ * `getInsights.days`.
18
+ */
19
+ import type { AnalyticsToolsHandle } from '../factory';
20
+ export interface McpTool {
21
+ name: string;
22
+ description: string;
23
+ inputSchema: Record<string, unknown>;
24
+ handler: (args: unknown) => Promise<{
25
+ content: {
26
+ type: 'text';
27
+ text: string;
28
+ }[];
29
+ isError?: boolean;
30
+ }>;
31
+ }
32
+ export declare function toMcpTools(handle: AnalyticsToolsHandle): McpTool[];
33
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/tools/mcp/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAEtD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;QAClC,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;QACzC,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB,CAAC,CAAA;CACH;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,EAAE,CAyClE"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * `toMcpTools` — adapt the six wrapped AI SDK v4 tools that back
3
+ * `AnalyticsToolsHandle` into the shape MCP servers speak.
4
+ *
5
+ * MCP servers want `{ name, description, inputSchema (JSON Schema),
6
+ * handler(args) => { content: [{ type: 'text', text }] } }`. Our
7
+ * factory returns AI SDK v4 tools whose `execute(args, opts) =>
8
+ * Promise<string>` already runs the full
9
+ * rate → auth → execute → budget → audit chain — so the adapter is
10
+ * a thin translation layer, not a second wrapper.
11
+ *
12
+ * The Zod parameter schemas are converted to JSON Schema draft-7 via
13
+ * `zod-to-json-schema` (drops `$schema` and `additionalProperties`
14
+ * so MCP clients get a compact tool descriptor). `.default()` values
15
+ * survive the conversion (asserted in the tests) so LLMs see the
16
+ * documented defaults on `detectAnomaly.stddevThreshold` and
17
+ * `getInsights.days`.
18
+ */
19
+ import { zodToJsonSchema } from 'zod-to-json-schema';
20
+ export function toMcpTools(handle) {
21
+ const entries = Object.entries(handle.tools);
22
+ return entries.map(([name, tool]) => {
23
+ const parameters = tool.parameters;
24
+ const rawSchema = zodToJsonSchema(parameters, {
25
+ target: 'jsonSchema7',
26
+ $refStrategy: 'none',
27
+ });
28
+ // Strip the top-level $schema marker — MCP clients don't need it,
29
+ // and its presence bloats every list_tools response.
30
+ const { $schema: _drop, ...inputSchema } = rawSchema;
31
+ return {
32
+ name: String(name),
33
+ description: tool.description ?? '',
34
+ inputSchema,
35
+ handler: async (args) => {
36
+ if (!tool.execute) {
37
+ return {
38
+ content: [{
39
+ type: 'text',
40
+ text: `Tool ${String(name)} is not executable.`,
41
+ }],
42
+ isError: true,
43
+ };
44
+ }
45
+ const text = await tool.execute(args, {
46
+ toolCallId: `mcp:${String(name)}`,
47
+ messages: [],
48
+ });
49
+ return {
50
+ content: [{ type: 'text', text: String(text) }],
51
+ };
52
+ },
53
+ };
54
+ });
55
+ }
56
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/tools/mcp/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAapD,MAAM,UAAU,UAAU,CAAC,MAA4B;IACrD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAGxC,CAAA;IAEH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAmD,CAAA;QAC3E,MAAM,SAAS,GAAG,eAAe,CAAC,UAAU,EAAE;YAC5C,MAAM,EAAE,aAAa;YACrB,YAAY,EAAE,MAAM;SACrB,CAA4B,CAAA;QAE7B,kEAAkE;QAClE,qDAAqD;QACrD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,WAAW,EAAE,GAAG,SAAS,CAAA;QAEpD,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;YAClB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;YACnC,WAAW;YACX,OAAO,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE;gBAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO;wBACL,OAAO,EAAE,CAAC;gCACR,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,QAAQ,MAAM,CAAC,IAAI,CAAC,qBAAqB;6BAChD,CAAC;wBACF,OAAO,EAAE,IAAI;qBACd,CAAA;gBACH,CAAC;gBACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAa,EAAE;oBAC7C,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE;oBACjC,QAAQ,EAAE,EAAE;iBACb,CAAC,CAAA;gBACF,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;iBACzD,CAAA;YACH,CAAC;SACF,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `shouldStartMcpServer` — cross-runtime dev flag for the MCP subpath.
3
+ *
4
+ * Returns `true` iff the process is a React Native dev build
5
+ * (`__DEV__ === true`) **or** the Node process has
6
+ * `ENABLE_MCP_SERVER=1` set. Prod RN builds have `__DEV__ === false`
7
+ * and no `process.env`, so the check returns `false` and the caller
8
+ * short-circuits — with `sideEffects: false` at the package root,
9
+ * this lets bundlers drop every module reachable only through the
10
+ * MCP subpath (including `@modelcontextprotocol/sdk`).
11
+ *
12
+ * The helper is intentionally pure — importing it does not itself
13
+ * import the SDK. Callers should gate SDK imports behind
14
+ * `shouldStartMcpServer()` at their entry point.
15
+ */
16
+ export declare function shouldStartMcpServer(): boolean;
17
+ //# sourceMappingURL=guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../../src/tools/mcp/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `shouldStartMcpServer` — cross-runtime dev flag for the MCP subpath.
3
+ *
4
+ * Returns `true` iff the process is a React Native dev build
5
+ * (`__DEV__ === true`) **or** the Node process has
6
+ * `ENABLE_MCP_SERVER=1` set. Prod RN builds have `__DEV__ === false`
7
+ * and no `process.env`, so the check returns `false` and the caller
8
+ * short-circuits — with `sideEffects: false` at the package root,
9
+ * this lets bundlers drop every module reachable only through the
10
+ * MCP subpath (including `@modelcontextprotocol/sdk`).
11
+ *
12
+ * The helper is intentionally pure — importing it does not itself
13
+ * import the SDK. Callers should gate SDK imports behind
14
+ * `shouldStartMcpServer()` at their entry point.
15
+ */
16
+ export function shouldStartMcpServer() {
17
+ const isRnDev = typeof __DEV__ !== 'undefined' && __DEV__ === true;
18
+ const isNodeFlag = typeof process !== 'undefined'
19
+ && process.env?.ENABLE_MCP_SERVER === '1';
20
+ return isRnDev || isNodeFlag;
21
+ }
22
+ //# sourceMappingURL=guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../src/tools/mcp/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,UAAU,oBAAoB;IAClC,MAAM,OAAO,GACT,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,IAAI,CAAA;IACtD,MAAM,UAAU,GACZ,OAAO,OAAO,KAAK,WAAW;WAC3B,OAAO,CAAC,GAAG,EAAE,iBAAiB,KAAK,GAAG,CAAA;IAC7C,OAAO,OAAO,IAAI,UAAU,CAAA;AAC9B,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `@mongrov/analytics/tools/mcp` — Model Context Protocol server for
3
+ * the six analytics tools. See `./README.md` for wiring examples.
4
+ *
5
+ * Importing this barrel does NOT itself construct a server. Callers
6
+ * gate SDK-touching code behind `shouldStartMcpServer()`; combined
7
+ * with the package's `sideEffects: false`, prod bundles reachable
8
+ * only through this subpath drop the `@modelcontextprotocol/sdk`
9
+ * runtime entirely.
10
+ */
11
+ export { toMcpTools } from './adapter';
12
+ export type { McpTool } from './adapter';
13
+ export { shouldStartMcpServer } from './guard';
14
+ export { createMcpServer } from './server';
15
+ export type { CreateMcpServerConfig, McpServerHandle, } from './server';
16
+ export { createStdioTransport } from './transports/stdio';
17
+ export type { CreateStdioTransportOptions } from './transports/stdio';
18
+ export { createHttpTransport } from './transports/http';
19
+ export type { CreateHttpTransportConfig, HttpTransportHandle, } from './transports/http';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,YAAY,EACV,qBAAqB,EACrB,eAAe,GAChB,MAAM,UAAU,CAAA;AAEjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,YAAY,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAA;AAErE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EACV,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `@mongrov/analytics/tools/mcp` — Model Context Protocol server for
3
+ * the six analytics tools. See `./README.md` for wiring examples.
4
+ *
5
+ * Importing this barrel does NOT itself construct a server. Callers
6
+ * gate SDK-touching code behind `shouldStartMcpServer()`; combined
7
+ * with the package's `sideEffects: false`, prod bundles reachable
8
+ * only through this subpath drop the `@modelcontextprotocol/sdk`
9
+ * runtime entirely.
10
+ */
11
+ export { toMcpTools } from './adapter';
12
+ export { shouldStartMcpServer } from './guard';
13
+ export { createMcpServer } from './server';
14
+ export { createStdioTransport } from './transports/stdio';
15
+ export { createHttpTransport } from './transports/http';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAGtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAM1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * `createMcpServer` — wrap an `AnalyticsToolsHandle` in an MCP server
3
+ * that speaks `tools/list` + `tools/call` to any MCP client.
4
+ *
5
+ * We use the low-level `Server` + `setRequestHandler` rather than the
6
+ * higher-level `McpServer.registerTool`, because `registerTool` wants
7
+ * either a Zod raw shape or an `AnySchema`, and our tools were built
8
+ * around `zod.object(...)` (not raw shapes) and are already converted
9
+ * to JSON Schema by `toMcpTools`. Emitting the pre-baked JSON Schema
10
+ * from `tools/list` keeps the source of truth in one place (the Zod
11
+ * schemas in `src/tools/impls/*.ts`).
12
+ *
13
+ * `call_tool` re-dispatches into the wrapped `tool.execute`, which
14
+ * runs the full rate → auth → execute → budget → audit chain via the
15
+ * ctx container the handle owns. `handle.setContext(...)` before an
16
+ * MCP session behaves identically to setting it before an AI SDK turn.
17
+ */
18
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
19
+ import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
20
+ import type { AnalyticsToolsHandle } from '../factory';
21
+ import type { ToolsLogger } from '../types';
22
+ export interface CreateMcpServerConfig {
23
+ toolsHandle: AnalyticsToolsHandle;
24
+ /** Server name advertised on `initialize`. Default `'mongrov-analytics'`. */
25
+ name?: string;
26
+ /** Server version advertised on `initialize`. Default `'0.1.0'`. */
27
+ version?: string;
28
+ logger?: ToolsLogger;
29
+ }
30
+ export interface McpServerHandle {
31
+ /** The underlying SDK server — exposed for advanced callers. */
32
+ server: Server;
33
+ /** Attach to a transport and start listening. */
34
+ connect: (transport: Transport) => Promise<void>;
35
+ /** Close the connection. Does NOT close the underlying tools handle. */
36
+ close: () => Promise<void>;
37
+ }
38
+ export declare function createMcpServer(config: CreateMcpServerConfig): McpServerHandle;
39
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/tools/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAA;AAK9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG3C,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,oBAAoB,CAAA;IACjC,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,wEAAwE;IACxE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,qBAAqB,GAC5B,eAAe,CA2DjB"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * `createMcpServer` — wrap an `AnalyticsToolsHandle` in an MCP server
3
+ * that speaks `tools/list` + `tools/call` to any MCP client.
4
+ *
5
+ * We use the low-level `Server` + `setRequestHandler` rather than the
6
+ * higher-level `McpServer.registerTool`, because `registerTool` wants
7
+ * either a Zod raw shape or an `AnySchema`, and our tools were built
8
+ * around `zod.object(...)` (not raw shapes) and are already converted
9
+ * to JSON Schema by `toMcpTools`. Emitting the pre-baked JSON Schema
10
+ * from `tools/list` keeps the source of truth in one place (the Zod
11
+ * schemas in `src/tools/impls/*.ts`).
12
+ *
13
+ * `call_tool` re-dispatches into the wrapped `tool.execute`, which
14
+ * runs the full rate → auth → execute → budget → audit chain via the
15
+ * ctx container the handle owns. `handle.setContext(...)` before an
16
+ * MCP session behaves identically to setting it before an AI SDK turn.
17
+ */
18
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
19
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
20
+ import { toMcpTools } from './adapter';
21
+ export function createMcpServer(config) {
22
+ const mcpTools = toMcpTools(config.toolsHandle);
23
+ const byName = new Map(mcpTools.map(t => [t.name, t]));
24
+ const server = new Server({
25
+ name: config.name ?? 'mongrov-analytics',
26
+ version: config.version ?? '0.1.0',
27
+ }, { capabilities: { tools: {} } });
28
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
29
+ tools: mcpTools.map(t => ({
30
+ name: t.name,
31
+ description: t.description,
32
+ inputSchema: t.inputSchema,
33
+ })),
34
+ }));
35
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
36
+ const tool = byName.get(req.params.name);
37
+ if (!tool) {
38
+ return {
39
+ content: [{
40
+ type: 'text',
41
+ text: `Unknown tool: ${req.params.name}`,
42
+ }],
43
+ isError: true,
44
+ };
45
+ }
46
+ try {
47
+ return await tool.handler(req.params.arguments ?? {});
48
+ }
49
+ catch (err) {
50
+ const message = err instanceof Error ? err.message : String(err);
51
+ config.logger?.error('mcp tool handler threw', {
52
+ toolName: req.params.name,
53
+ err: message,
54
+ });
55
+ return {
56
+ content: [{
57
+ type: 'text',
58
+ text: `Tool call failed.`,
59
+ }],
60
+ isError: true,
61
+ };
62
+ }
63
+ });
64
+ return {
65
+ server,
66
+ connect: transport => server.connect(transport),
67
+ close: () => server.close(),
68
+ };
69
+ }
70
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/tools/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAElE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAA;AAG3C,OAAO,EAAgB,UAAU,EAAE,MAAM,WAAW,CAAA;AAoBpD,MAAM,UAAU,eAAe,CAC7B,MAA6B;IAE7B,MAAM,QAAQ,GAAc,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAU,CAAC,CAAC,CAAA;IAE/D,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;QACE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,mBAAmB;QACxC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO;KACnC,EACD,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAA;IAED,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,CAAC,CAAC,WAId;SACF,CAAC,CAAC;KACJ,CAAC,CAAC,CAAA;IAEH,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,iBAAiB,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;qBACzC,CAAC;gBACF,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;QACD,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;QACvD,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAChE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,wBAAwB,EAAE;gBAC7C,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI;gBACzB,GAAG,EAAE,OAAO;aACb,CAAC,CAAA;YACF,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,mBAAmB;qBAC1B,CAAC;gBACF,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,MAAM;QACN,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;QAC/C,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE;KAC5B,CAAA;AACH,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * `createHttpTransport` — Node HTTP transport for `createMcpServer`.
3
+ *
4
+ * Boots a bare `node:http` server that gates requests behind an
5
+ * optional bearer token, then hands them to the SDK's
6
+ * `StreamableHTTPServerTransport`. Runs in stateless mode
7
+ * (no `sessionIdGenerator`) — every request is self-contained, which
8
+ * matches how our tools are already wired (`handle.setContext(...)`
9
+ * carries the per-user scope, not the transport).
10
+ *
11
+ * Deliberately minimal:
12
+ * - one path (default `/mcp`)
13
+ * - one method (POST + GET both dispatched to the SDK)
14
+ * - bearer via `Authorization: Bearer <token>`, constant-time cmp
15
+ * - unauthenticated boot logs a warn but is allowed for local dev
16
+ *
17
+ * Meaningful only under Node; RN builds should never import this
18
+ * module — the guard + `sideEffects: false` keep it out of prod
19
+ * bundles.
20
+ *
21
+ * Callers wire it as:
22
+ * const t = await createHttpTransport({ port: 8787, authToken: 'x' })
23
+ * await mcpServer.connect(t.transport)
24
+ * // ...
25
+ * await t.close()
26
+ */
27
+ import type { Server as HttpServer } from 'node:http';
28
+ import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
29
+ import type { ToolsLogger } from '../../types';
30
+ export interface CreateHttpTransportConfig {
31
+ /** Listening port. `0` picks an ephemeral port (tests). Default `0`. */
32
+ port?: number;
33
+ /** URL path. Default `/mcp`. */
34
+ path?: string;
35
+ /**
36
+ * Optional bearer token. If set, incoming requests must present
37
+ * `Authorization: Bearer <authToken>` or get a 401. If unset, all
38
+ * requests pass — logged as a warn on boot.
39
+ */
40
+ authToken?: string;
41
+ logger?: ToolsLogger;
42
+ }
43
+ export interface HttpTransportHandle {
44
+ /** The SDK transport — hand to `mcpServer.connect(...)`. */
45
+ transport: Transport;
46
+ /** The Node HTTP server — exposed for advanced callers. */
47
+ server: HttpServer;
48
+ /** Actual listening port (resolved when `port: 0`). */
49
+ port: number;
50
+ /** Shut down the HTTP server + transport. */
51
+ close: () => Promise<void>;
52
+ }
53
+ export declare function createHttpTransport(config?: CreateHttpTransportConfig): Promise<HttpTransportHandle>;
54
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/tools/mcp/transports/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAmB,MAAM,IAAI,UAAU,EAAkB,MAAM,WAAW,CAAA;AAItF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAA;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,MAAM,WAAW,yBAAyB;IACxC,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,SAAS,EAAE,SAAS,CAAA;IACpB,2DAA2D;IAC3D,MAAM,EAAE,UAAU,CAAA;IAClB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAgCD,wBAAsB,mBAAmB,CACvC,MAAM,GAAE,yBAA8B,GACrC,OAAO,CAAC,mBAAmB,CAAC,CAkF9B"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * `createHttpTransport` — Node HTTP transport for `createMcpServer`.
3
+ *
4
+ * Boots a bare `node:http` server that gates requests behind an
5
+ * optional bearer token, then hands them to the SDK's
6
+ * `StreamableHTTPServerTransport`. Runs in stateless mode
7
+ * (no `sessionIdGenerator`) — every request is self-contained, which
8
+ * matches how our tools are already wired (`handle.setContext(...)`
9
+ * carries the per-user scope, not the transport).
10
+ *
11
+ * Deliberately minimal:
12
+ * - one path (default `/mcp`)
13
+ * - one method (POST + GET both dispatched to the SDK)
14
+ * - bearer via `Authorization: Bearer <token>`, constant-time cmp
15
+ * - unauthenticated boot logs a warn but is allowed for local dev
16
+ *
17
+ * Meaningful only under Node; RN builds should never import this
18
+ * module — the guard + `sideEffects: false` keep it out of prod
19
+ * bundles.
20
+ *
21
+ * Callers wire it as:
22
+ * const t = await createHttpTransport({ port: 8787, authToken: 'x' })
23
+ * await mcpServer.connect(t.transport)
24
+ * // ...
25
+ * await t.close()
26
+ */
27
+ import { timingSafeEqual } from 'node:crypto';
28
+ import { createServer } from 'node:http';
29
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
30
+ const UNAUTHORIZED_BODY = 'Unauthorized\n';
31
+ const NOT_FOUND_BODY = 'Not Found\n';
32
+ function bearerMatches(header, expected) {
33
+ if (!header || !header.startsWith('Bearer '))
34
+ return false;
35
+ const presented = header.slice('Bearer '.length);
36
+ const a = Buffer.from(presented);
37
+ const b = Buffer.from(expected);
38
+ if (a.length !== b.length)
39
+ return false;
40
+ return timingSafeEqual(a, b);
41
+ }
42
+ async function readBody(req) {
43
+ return new Promise((resolve, reject) => {
44
+ const chunks = [];
45
+ req.on('data', (c) => chunks.push(c));
46
+ req.on('end', () => {
47
+ if (chunks.length === 0)
48
+ return resolve(undefined);
49
+ const raw = Buffer.concat(chunks).toString('utf8');
50
+ try {
51
+ resolve(raw.length > 0 ? JSON.parse(raw) : undefined);
52
+ }
53
+ catch (err) {
54
+ reject(err instanceof Error ? err : new Error(String(err)));
55
+ }
56
+ });
57
+ req.on('error', reject);
58
+ });
59
+ }
60
+ export async function createHttpTransport(config = {}) {
61
+ const port = config.port ?? 0;
62
+ const path = config.path ?? '/mcp';
63
+ const authToken = config.authToken;
64
+ if (!authToken) {
65
+ config.logger?.warn('MCP HTTP transport started without authToken — do not expose to untrusted networks');
66
+ }
67
+ const transport = new StreamableHTTPServerTransport({
68
+ sessionIdGenerator: undefined,
69
+ });
70
+ const server = createServer((req, res) => {
71
+ // Path check — only the configured path is dispatched.
72
+ const url = req.url ?? '';
73
+ const [reqPath] = url.split('?');
74
+ if (reqPath !== path) {
75
+ res.statusCode = 404;
76
+ res.setHeader('content-type', 'text/plain');
77
+ res.end(NOT_FOUND_BODY);
78
+ return;
79
+ }
80
+ // Bearer check.
81
+ if (authToken) {
82
+ const header = req.headers.authorization;
83
+ if (!bearerMatches(header, authToken)) {
84
+ res.statusCode = 401;
85
+ res.setHeader('content-type', 'text/plain');
86
+ res.setHeader('www-authenticate', 'Bearer');
87
+ res.end(UNAUTHORIZED_BODY);
88
+ return;
89
+ }
90
+ }
91
+ // Body parse (POST) then dispatch.
92
+ void (async () => {
93
+ try {
94
+ const body = req.method === 'POST' ? await readBody(req) : undefined;
95
+ await transport.handleRequest(req, res, body);
96
+ }
97
+ catch (err) {
98
+ config.logger?.error('MCP HTTP transport request handler threw', {
99
+ err: err instanceof Error ? err.message : String(err),
100
+ });
101
+ if (!res.headersSent) {
102
+ res.statusCode = 500;
103
+ res.setHeader('content-type', 'text/plain');
104
+ res.end('Internal Server Error\n');
105
+ }
106
+ else {
107
+ res.end();
108
+ }
109
+ }
110
+ })();
111
+ });
112
+ await new Promise((resolve, reject) => {
113
+ server.once('error', reject);
114
+ server.listen(port, () => {
115
+ server.off('error', reject);
116
+ resolve();
117
+ });
118
+ });
119
+ const address = server.address();
120
+ const resolvedPort = address?.port ?? port;
121
+ return {
122
+ transport,
123
+ server,
124
+ port: resolvedPort,
125
+ close: async () => {
126
+ await new Promise((resolve) => {
127
+ server.close(() => resolve());
128
+ });
129
+ await transport.close();
130
+ },
131
+ };
132
+ }
133
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../../src/tools/mcp/transports/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `createStdioTransport` — Node stdio transport for `createMcpServer`.
3
+ *
4
+ * Reads MCP framed messages off `process.stdin` and writes them to
5
+ * `process.stdout`. Meaningful only under Node; on Hermes there is no
6
+ * stdio pipe. Callers should gate construction behind
7
+ * `shouldStartMcpServer()` so this module is never imported in prod
8
+ * RN builds (and its `node:stream` peer disappears with the rest of
9
+ * the MCP subpath under `sideEffects: false`).
10
+ *
11
+ * The SDK's `StdioServerTransport` accepts optional `stdin` / `stdout`
12
+ * streams; we expose the same knobs for tests that want to pipe
13
+ * fixtures without touching real stdio.
14
+ */
15
+ import type { Readable, Writable } from 'node:stream';
16
+ import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
17
+ export interface CreateStdioTransportOptions {
18
+ stdin?: Readable;
19
+ stdout?: Writable;
20
+ }
21
+ export declare function createStdioTransport(options?: CreateStdioTransportOptions): Transport;
22
+ //# sourceMappingURL=stdio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../../../src/tools/mcp/transports/stdio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAA;AAE9E,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,MAAM,CAAC,EAAE,QAAQ,CAAA;CAClB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,2BAAgC,GACxC,SAAS,CAEX"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `createStdioTransport` — Node stdio transport for `createMcpServer`.
3
+ *
4
+ * Reads MCP framed messages off `process.stdin` and writes them to
5
+ * `process.stdout`. Meaningful only under Node; on Hermes there is no
6
+ * stdio pipe. Callers should gate construction behind
7
+ * `shouldStartMcpServer()` so this module is never imported in prod
8
+ * RN builds (and its `node:stream` peer disappears with the rest of
9
+ * the MCP subpath under `sideEffects: false`).
10
+ *
11
+ * The SDK's `StdioServerTransport` accepts optional `stdin` / `stdout`
12
+ * streams; we expose the same knobs for tests that want to pipe
13
+ * fixtures without touching real stdio.
14
+ */
15
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
16
+ export function createStdioTransport(options = {}) {
17
+ return new StdioServerTransport(options.stdin, options.stdout);
18
+ }
19
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../../../src/tools/mcp/transports/stdio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAQhF,MAAM,UAAU,oBAAoB,CAClC,UAAuC,EAAE;IAEzC,OAAO,IAAI,oBAAoB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;AAChE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@mongrov/analytics",
3
- "version": "0.1.0-alpha.9",
3
+ "version": "0.1.0",
4
+ "sideEffects": false,
4
5
  "description": "DuckDB + R2 Iceberg local analytics for @mongrov apps",
5
6
  "license": "MIT",
6
7
  "repository": {
@@ -38,6 +39,11 @@
38
39
  "import": "./dist/tools/index.js",
39
40
  "default": "./dist/tools/index.js"
40
41
  },
42
+ "./tools/mcp": {
43
+ "types": "./dist/tools/mcp/index.d.ts",
44
+ "import": "./dist/tools/mcp/index.js",
45
+ "default": "./dist/tools/mcp/index.js"
46
+ },
41
47
  "./sync": {
42
48
  "types": "./dist/sync/index.d.ts",
43
49
  "import": "./dist/sync/index.js",
@@ -52,24 +58,19 @@
52
58
  "files": [
53
59
  "dist"
54
60
  ],
55
- "scripts": {
56
- "build": "tsc -p tsconfig.build.json",
57
- "clean": "rm -rf dist",
58
- "prebuild": "pnpm run clean",
59
- "test": "vitest run",
60
- "test:watch": "vitest",
61
- "typecheck": "tsc --noEmit",
62
- "prepublishOnly": "pnpm run build"
63
- },
64
61
  "peerDependencies": {
65
- "@mongrov/db": "workspace:*",
62
+ "@modelcontextprotocol/sdk": ">=1.20.0",
66
63
  "@mongrov/types": "^0.4.0",
67
64
  "ai": ">=4",
68
65
  "react": ">=19",
69
66
  "react-native": ">=0.81",
70
- "react-native-duckdb": ">=1.0.0"
67
+ "react-native-duckdb": ">=1.0.0",
68
+ "@mongrov/db": "0.3.0"
71
69
  },
72
70
  "peerDependenciesMeta": {
71
+ "@modelcontextprotocol/sdk": {
72
+ "optional": true
73
+ },
73
74
  "react": {
74
75
  "optional": true
75
76
  },
@@ -84,12 +85,15 @@
84
85
  "@iarna/toml": "^2.2.5",
85
86
  "date-fns-tz": "^3.2.0",
86
87
  "p-queue": "^8.0.1",
87
- "xstate": "^5.30.0"
88
+ "xstate": "^5.30.0",
89
+ "zod-to-json-schema": "^3.25.2"
88
90
  },
89
91
  "devDependencies": {
90
- "@mongrov/db": "workspace:*",
91
- "@mongrov/types": "workspace:*",
92
+ "@duckdb/node-api": "1.5.4-r.1",
93
+ "@duckdb/node-bindings": "1.5.4-r.1",
94
+ "@modelcontextprotocol/sdk": "^1.29.0",
92
95
  "@testing-library/react": "^14.3.1",
96
+ "@types/node": "^25.6.0",
93
97
  "@types/react": "^18.3.12",
94
98
  "@types/react-dom": "^18.3.1",
95
99
  "ai": "^4.3.0",
@@ -99,6 +103,17 @@
99
103
  "react-dom": "^18.3.1",
100
104
  "typescript": "^5.9.3",
101
105
  "vitest": "^2.1.9",
102
- "zod": "^3.23.8"
106
+ "zod": "^3.23.8",
107
+ "@mongrov/db": "0.3.0",
108
+ "@mongrov/types": "0.4.0"
109
+ },
110
+ "scripts": {
111
+ "build": "tsc -p tsconfig.build.json",
112
+ "clean": "rm -rf dist",
113
+ "prebuild": "pnpm run clean",
114
+ "test": "vitest run",
115
+ "test:watch": "vitest",
116
+ "test:integration": "vitest run --config vitest.integration.config.ts",
117
+ "typecheck": "tsc --noEmit"
103
118
  }
104
- }
119
+ }