@steno-ai/mcp 0.1.1 → 0.1.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@ export interface LocalServerConfig {
15
15
  scopeId: string;
16
16
  embeddingModel: string;
17
17
  embeddingDim: number;
18
+ domainEntityTypes?: import('../../engine/src/config.js').DomainEntityType[];
18
19
  }
19
20
  export declare function createLocalServer(config: LocalServerConfig): McpServer;
20
21
  //# sourceMappingURL=local-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-server.d.ts","sourceRoot":"","sources":["../src/local-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAqQtE"}
1
+ {"version":3,"file":"local-server.d.ts","sourceRoot":"","sources":["../src/local-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,4BAA4B,EAAE,gBAAgB,EAAE,CAAC;CAC7E;AAkDD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAsTtE"}
@@ -4,14 +4,60 @@
4
4
  */
5
5
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
6
  import { z } from 'zod';
7
+ const FLUSH_DELAY_MS = 30_000; // 30 seconds of inactivity triggers flush
8
+ const MAX_BUFFER_SIZE = 5; // flush after 5 messages
9
+ // In-memory embedding cache — survives across tool calls within the same MCP session
10
+ let _embeddingCache = null;
11
+ function getEmbeddingCache() {
12
+ if (!_embeddingCache)
13
+ _embeddingCache = new Map();
14
+ return _embeddingCache;
15
+ }
16
+ /** Simple cache adapter that wraps a Map for embedding caching */
17
+ const embeddingCacheAdapter = {
18
+ async get(key) {
19
+ const cache = getEmbeddingCache();
20
+ const entry = cache.get(key);
21
+ if (!entry)
22
+ return null;
23
+ // TTL: 10 minutes
24
+ if (Date.now() - entry.ts > 600_000) {
25
+ cache.delete(key);
26
+ return null;
27
+ }
28
+ return entry.embedding;
29
+ },
30
+ async set(key, value) {
31
+ const cache = getEmbeddingCache();
32
+ cache.set(key, { embedding: value, ts: Date.now() });
33
+ // Evict old entries if cache grows too large (>500 entries)
34
+ if (cache.size > 500) {
35
+ const oldest = [...cache.entries()].sort((a, b) => a[1].ts - b[1].ts).slice(0, 100);
36
+ for (const [k] of oldest)
37
+ cache.delete(k);
38
+ }
39
+ },
40
+ async del(key) { getEmbeddingCache().delete(key); },
41
+ async incr() { return 0; },
42
+ async expire() { },
43
+ async ping() { return true; },
44
+ };
7
45
  export function createLocalServer(config) {
8
46
  const server = new McpServer({
9
47
  name: 'steno-local',
10
48
  version: '0.1.0',
49
+ instructions: `You have access to the user's persistent long-term memory via Steno.
50
+
51
+ CRITICAL RULES:
52
+ 1. ALWAYS call steno_recall BEFORE answering ANY question about the user, their life, work, projects, people they know, preferences, past events, companies, or decisions. Do this BEFORE using web search or "Relevant chats".
53
+ 2. When the user shares personal information, experiences, opinions, or decisions, call steno_remember to store it.
54
+ 3. Never say "I don't have information about that" without first checking steno_recall.
55
+ 4. Steno memory persists across ALL conversations — it knows things from past sessions that your conversation history does not.`,
11
56
  });
12
57
  // Lazy import to avoid loading heavy modules at startup
13
58
  let _search = null;
14
59
  let _pipeline = null;
60
+ let _getOrCreateActiveSession = null;
15
61
  async function getSearch() {
16
62
  if (!_search) {
17
63
  const mod = await import('../../engine/src/retrieval/search.js');
@@ -26,8 +72,82 @@ export function createLocalServer(config) {
26
72
  }
27
73
  return _pipeline;
28
74
  }
75
+ async function getSessionManager() {
76
+ if (!_getOrCreateActiveSession) {
77
+ const mod = await import('../../engine/src/sessions/manager.js');
78
+ _getOrCreateActiveSession = mod.getOrCreateActiveSession;
79
+ }
80
+ return _getOrCreateActiveSession;
81
+ }
82
+ // ---------------------------------------------------------------------------
83
+ // Session buffer — accumulate messages, flush periodically
84
+ // ---------------------------------------------------------------------------
85
+ const sessionBuffers = new Map();
86
+ /** Build a buffer key from scope parameters */
87
+ function bufferKey() {
88
+ return `${config.tenantId}:${config.scope}:${config.scopeId}`;
89
+ }
90
+ /** Flush the session buffer: run extraction pipeline on all accumulated messages */
91
+ async function flushBuffer(key) {
92
+ const buf = sessionBuffers.get(key);
93
+ if (!buf || buf.messages.length === 0)
94
+ return;
95
+ // Grab and clear the buffer immediately so new messages start a fresh batch
96
+ const messages = [...buf.messages];
97
+ const sessionId = buf.sessionId;
98
+ buf.messages = [];
99
+ if (buf.flushTimer) {
100
+ clearTimeout(buf.flushTimer);
101
+ buf.flushTimer = null;
102
+ }
103
+ const fullText = messages.join('\n---\n');
104
+ console.error(`[steno] Flushing session buffer: ${messages.length} messages, sessionId=${sessionId}`);
105
+ try {
106
+ const runPipeline = await getPipeline();
107
+ const result = await runPipeline({
108
+ storage: config.storage,
109
+ embedding: config.embedding,
110
+ cheapLLM: config.cheapLLM,
111
+ embeddingModel: config.embeddingModel,
112
+ embeddingDim: config.embeddingDim,
113
+ extractionTier: 'auto',
114
+ domainEntityTypes: config.domainEntityTypes,
115
+ }, {
116
+ tenantId: config.tenantId,
117
+ scope: config.scope,
118
+ scopeId: config.scopeId,
119
+ sessionId,
120
+ inputType: 'raw_text',
121
+ data: fullText,
122
+ });
123
+ console.error(`[steno] Session flush done: ${result.factsCreated} facts, ${result.entitiesCreated} entities, ${result.edgesCreated} edges`);
124
+ }
125
+ catch (err) {
126
+ console.error('[steno] Session flush pipeline error:', err?.message ?? err);
127
+ }
128
+ }
129
+ /** Schedule a flush after the inactivity delay, or flush immediately if buffer is full */
130
+ function scheduleFlush(key) {
131
+ const buf = sessionBuffers.get(key);
132
+ if (!buf)
133
+ return;
134
+ // Clear any existing timer
135
+ if (buf.flushTimer) {
136
+ clearTimeout(buf.flushTimer);
137
+ buf.flushTimer = null;
138
+ }
139
+ // Flush immediately if buffer is full
140
+ if (buf.messages.length >= MAX_BUFFER_SIZE) {
141
+ void flushBuffer(key);
142
+ return;
143
+ }
144
+ // Otherwise schedule a delayed flush
145
+ buf.flushTimer = setTimeout(() => {
146
+ void flushBuffer(key);
147
+ }, FLUSH_DELAY_MS);
148
+ }
29
149
  // ─── REMEMBER ───
30
- server.tool('steno_remember', 'Store information in long-term memory. Use this to remember facts, preferences, decisions, or anything worth recalling later.', {
150
+ server.tool('steno_remember', 'Store important information in the user\'s persistent long-term memory. ALWAYS use this to save facts, preferences, decisions, experiences, people, companies, events, or anything the user shares that they might want recalled later. This memory persists across ALL conversations and devices.', {
31
151
  content: z.string().optional().describe('What to remember'),
32
152
  text: z.string().optional().describe('What to remember (alias for content)'),
33
153
  }, async (args) => {
@@ -35,133 +155,73 @@ export function createLocalServer(config) {
35
155
  if (!memoryText) {
36
156
  return { content: [{ type: 'text', text: 'Error: provide content or text' }] };
37
157
  }
38
- // FAST PATH: For short, already-clean facts (< 200 chars, single sentence),
39
- // skip the LLM extraction pipeline and store directly. ~200ms vs ~5000ms.
40
- const isSingleFact = memoryText.length < 200 && !memoryText.includes('\n') && memoryText.split('.').length <= 2;
41
- if (isSingleFact) {
42
- const factId = crypto.randomUUID();
43
- const embedding = await config.embedding.embed(memoryText);
44
- // Ensure "User" entity exists and link fact to it
45
- let userEntityId;
158
+ // ── Session-based buffering ──
159
+ // Accumulate messages within a session. Extraction runs when the buffer
160
+ // is full (MAX_BUFFER_SIZE) or after an inactivity timeout (FLUSH_DELAY_MS).
161
+ const key = bufferKey();
162
+ let buf = sessionBuffers.get(key);
163
+ if (!buf) {
164
+ // Start or resume a session
165
+ let sessionId;
46
166
  try {
47
- const existing = await config.storage.findEntityByCanonicalName(config.tenantId, 'user', 'person');
48
- if (existing) {
49
- userEntityId = existing.id;
50
- }
51
- else {
52
- userEntityId = crypto.randomUUID();
53
- await config.storage.createEntity({
54
- id: userEntityId, tenantId: config.tenantId, name: 'User',
55
- entityType: 'person', canonicalName: 'user', properties: {},
56
- embedding: await config.embedding.embed('User'),
57
- embeddingModel: config.embeddingModel, embeddingDim: config.embeddingDim,
58
- });
59
- }
167
+ const getOrCreate = await getSessionManager();
168
+ // SessionScope excludes 'session', but config.scope might be 'session'.
169
+ // Treat 'session' scope as 'user' for session tracking purposes.
170
+ const sessionScope = config.scope === 'session' ? 'user' : config.scope;
171
+ const session = await getOrCreate(config.storage, config.tenantId, sessionScope, config.scopeId);
172
+ sessionId = session.id;
60
173
  }
61
- catch { }
62
- const linkToUser = async (fid) => {
63
- if (userEntityId) {
64
- try {
65
- await config.storage.linkFactEntity(fid, userEntityId, 'mentioned');
66
- }
67
- catch { }
68
- }
69
- };
70
- // Quick dedup check — see if very similar fact exists
71
- const matches = await config.storage.vectorSearch({
72
- embedding,
73
- tenantId: config.tenantId,
74
- scope: config.scope,
75
- scopeId: config.scopeId,
76
- limit: 1,
77
- minSimilarity: 0.85,
78
- validOnly: true,
79
- });
80
- if (matches.length > 0) {
81
- // Similar fact exists — create new version (Git-style append-only, never invalidate)
82
- const oldFact = matches[0].fact;
83
- await config.storage.createFact({
84
- id: factId,
85
- lineageId: oldFact.lineageId ?? crypto.randomUUID(),
86
- tenantId: config.tenantId,
87
- scope: config.scope,
88
- scopeId: config.scopeId,
89
- content: memoryText,
90
- embeddingModel: config.embeddingModel,
91
- embeddingDim: config.embeddingDim,
92
- embedding,
93
- importance: 0.7,
94
- confidence: 1.0,
95
- operation: 'update',
96
- sourceType: 'api',
97
- modality: 'text',
98
- tags: ['direct'],
99
- metadata: {},
100
- contradictionStatus: 'none',
101
- });
102
- await linkToUser(factId);
103
- return {
104
- content: [{ type: 'text', text: `Updated memory (new version created)` }],
105
- };
174
+ catch (err) {
175
+ console.error('[steno] Failed to create session, using ephemeral ID:', err?.message ?? err);
176
+ sessionId = crypto.randomUUID();
106
177
  }
107
- // No similar fact — create new
108
- await config.storage.createFact({
109
- id: factId,
110
- lineageId: crypto.randomUUID(),
111
- tenantId: config.tenantId,
112
- scope: config.scope,
113
- scopeId: config.scopeId,
114
- content: memoryText,
115
- embeddingModel: config.embeddingModel,
116
- embeddingDim: config.embeddingDim,
117
- embedding,
118
- importance: 0.7,
119
- confidence: 1.0,
120
- operation: 'create',
121
- sourceType: 'api',
122
- modality: 'text',
123
- tags: ['direct'],
124
- metadata: {},
125
- contradictionStatus: 'none',
126
- });
127
- await linkToUser(factId);
128
- return {
129
- content: [{ type: 'text', text: `Remembered` }],
178
+ buf = {
179
+ sessionId,
180
+ messages: [],
181
+ lastActivity: new Date(),
182
+ flushTimer: null,
130
183
  };
184
+ sessionBuffers.set(key, buf);
131
185
  }
132
- // FULL PATH: For longer text, multi-sentence content, conversations.
133
- // Runs LLM extraction + graph building + dedup. ~3-8 seconds.
134
- const runPipeline = await getPipeline();
135
- const result = await runPipeline({
136
- storage: config.storage,
137
- embedding: config.embedding,
138
- cheapLLM: config.cheapLLM,
139
- embeddingModel: config.embeddingModel,
140
- embeddingDim: config.embeddingDim,
141
- extractionTier: 'auto',
142
- }, {
143
- tenantId: config.tenantId,
144
- scope: config.scope,
145
- scopeId: config.scopeId,
146
- inputType: 'raw_text',
147
- data: memoryText,
148
- });
186
+ // Buffer the message
187
+ buf.messages.push(memoryText);
188
+ buf.lastActivity = new Date();
189
+ // ALL messages go through the full pipeline via session buffer (no fast path).
190
+ // Full pipeline gives us: LLM extraction, entity/edge creation,
191
+ // contextual embeddings, temporal grounding, dedup — everything.
192
+ // Returns immediately — extraction happens in the background when flushed.
193
+ scheduleFlush(key);
194
+ const pending = buf.messages.length;
149
195
  return {
150
- content: [
151
- {
152
- type: 'text',
153
- text: `Remembered (${result.factsCreated} facts, ${result.entitiesCreated} entities, ${result.edgesCreated} edges)`,
154
- },
155
- ],
196
+ content: [{ type: 'text', text: `Buffered (${pending}/${MAX_BUFFER_SIZE} messages in session). Extraction runs on flush.` }],
197
+ };
198
+ });
199
+ // ─── FLUSH ───
200
+ server.tool('steno_flush', 'Force extraction of all buffered session messages. Use before searching if you just stored information and need it immediately available.', {}, async () => {
201
+ const key = bufferKey();
202
+ const buf = sessionBuffers.get(key);
203
+ if (!buf || buf.messages.length === 0) {
204
+ return { content: [{ type: 'text', text: 'No buffered messages to flush.' }] };
205
+ }
206
+ const count = buf.messages.length;
207
+ await flushBuffer(key);
208
+ return {
209
+ content: [{ type: 'text', text: `Flushed ${count} buffered messages. Extraction complete.` }],
156
210
  };
157
211
  });
158
212
  // ─── RECALL ───
159
- server.tool('steno_recall', 'Search long-term memory for relevant information. Use this when you need context about the user, their preferences, past decisions, or any previously stored knowledge.', {
213
+ server.tool('steno_recall', 'ALWAYS search this memory before answering questions about the user, their life, work, projects, preferences, people they know, companies, events, or anything personal. This contains the user\'s persistent memory across all conversations. Search here FIRST before using web search or saying you don\'t know.', {
160
214
  query: z.string().describe('What to search for in memory'),
161
215
  limit: z.number().optional().describe('Max results (default 10)'),
162
216
  }, async ({ query, limit }) => {
217
+ // Auto-flush any pending buffered messages before searching
218
+ const key = bufferKey();
219
+ const buf = sessionBuffers.get(key);
220
+ if (buf && buf.messages.length > 0) {
221
+ await flushBuffer(key);
222
+ }
163
223
  const searchFn = await getSearch();
164
- const results = await searchFn({ storage: config.storage, embedding: config.embedding }, {
224
+ const results = await searchFn({ storage: config.storage, embedding: config.embedding, cache: embeddingCacheAdapter }, {
165
225
  query,
166
226
  tenantId: config.tenantId,
167
227
  scope: config.scope,
@@ -172,12 +232,23 @@ export function createLocalServer(config) {
172
232
  return { content: [{ type: 'text', text: 'No memories found.' }] };
173
233
  }
174
234
  const text = results.results
175
- .map((r, i) => {
235
+ .map((r) => {
236
+ const dateParts = [];
237
+ if (r.fact.eventDate)
238
+ dateParts.push(`event: ${new Date(r.fact.eventDate).toISOString().slice(0, 10)}`);
239
+ if (r.fact.documentDate)
240
+ dateParts.push(`doc: ${new Date(r.fact.documentDate).toISOString().slice(0, 10)}`);
241
+ const dateStr = dateParts.length > 0 ? `, ${dateParts.join(', ')}` : '';
176
242
  const signals = Object.entries(r.signals)
177
243
  .filter(([, v]) => v > 0)
178
244
  .map(([k, v]) => `${k.replace('Score', '')}=${v.toFixed(2)}`)
179
245
  .join(', ');
180
- return `${i + 1}. [${r.score.toFixed(2)}] ${r.fact.content}${signals ? ` (${signals})` : ''}`;
246
+ let line = `[Memory] ${r.fact.content} (score: ${r.score.toFixed(2)}${dateStr}${signals ? `, ${signals}` : ''})`;
247
+ if (r.fact.sourceChunk) {
248
+ line += `\n[Source Context] ${r.fact.sourceChunk}`;
249
+ }
250
+ line += '\n---';
251
+ return line;
181
252
  })
182
253
  .join('\n');
183
254
  return {
@@ -211,12 +282,12 @@ export function createLocalServer(config) {
211
282
  // ─── STATS ───
212
283
  server.tool('steno_stats', 'Get memory statistics — how many facts, entities, and edges are stored.', {}, async () => {
213
284
  const facts = await config.storage.getFactsByScope(config.tenantId, config.scope, config.scopeId, { limit: 1 });
214
- const entities = await config.storage.getEntitiesForTenant(config.tenantId);
285
+ const entities = await config.storage.getEntitiesForTenant(config.tenantId, { limit: 1 });
215
286
  return {
216
287
  content: [
217
288
  {
218
289
  type: 'text',
219
- text: `Memory stats:\n Facts: ${facts.hasMore ? '100+' : facts.data.length}\n Entities: ${entities.length}`,
290
+ text: `Memory stats:\n Facts: ${facts.hasMore ? '100+' : facts.data.length}\n Entities: ${entities.hasMore ? '100+' : entities.data.length}`,
220
291
  },
221
292
  ],
222
293
  };
@@ -1 +1 @@
1
- {"version":3,"file":"local-server.js","sourceRoot":"","sources":["../src/local-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,MAAM,UAAU,iBAAiB,CAAC,MAAyB;IACzD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,wDAAwD;IACxD,IAAI,OAAO,GAAwE,IAAI,CAAC;IACxF,IAAI,SAAS,GAA0F,IAAI,CAAC;IAE5G,KAAK,UAAU,SAAS;QACtB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,sCAAsC,CAAC,CAAC;YACjE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC;QACvB,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,UAAU,WAAW;QACxB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,yCAAyC,CAAC,CAAC;YACpE,SAAS,GAAG,GAAG,CAAC,qBAAqB,CAAC;QACxC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,+HAA+H,EAC/H;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC3D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;KAC7E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC;QAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC,EAAE,CAAC;QAC1F,CAAC;QAED,4EAA4E;QAC5E,0EAA0E;QAC1E,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;QAEhH,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAE3D,kDAAkD;YAClD,IAAI,YAAgC,CAAC;YACrC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACnG,IAAI,QAAQ,EAAE,CAAC;oBACb,YAAY,GAAG,QAAQ,CAAC,EAAE,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,YAAY,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;oBACnC,MAAM,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;wBAChC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM;wBACzD,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE;wBAC3D,SAAS,EAAE,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;wBAC/C,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY;qBACzE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAEV,MAAM,UAAU,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE;gBACvC,IAAI,YAAY,EAAE,CAAC;oBACjB,IAAI,CAAC;wBAAC,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;gBACvF,CAAC;YACH,CAAC,CAAC;YAEF,sDAAsD;YACtD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;gBAChD,SAAS;gBACT,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,KAAK,EAAE,CAAC;gBACR,aAAa,EAAE,IAAI;gBACnB,SAAS,EAAE,IAAI;aAChB,CAAC,CAAC;YAEH,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,qFAAqF;gBACrF,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAChC,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;oBAC9B,EAAE,EAAE,MAAM;oBACV,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE;oBACnD,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,OAAO,EAAE,UAAU;oBACnB,cAAc,EAAE,MAAM,CAAC,cAAc;oBACrC,YAAY,EAAE,MAAM,CAAC,YAAY;oBACjC,SAAS;oBACT,UAAU,EAAE,GAAG;oBACf,UAAU,EAAE,GAAG;oBACf,SAAS,EAAE,QAAQ;oBACnB,UAAU,EAAE,KAAK;oBACjB,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,CAAC,QAAQ,CAAC;oBAChB,QAAQ,EAAE,EAAE;oBACZ,mBAAmB,EAAE,MAAM;iBAC5B,CAAC,CAAC;gBACH,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,sCAAsC,EAAE,CAAC;iBACnF,CAAC;YACJ,CAAC;YAED,+BAA+B;YAC/B,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;gBAC9B,EAAE,EAAE,MAAM;gBACV,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE;gBAC9B,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,UAAU;gBACnB,cAAc,EAAE,MAAM,CAAC,cAAc;gBACrC,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,SAAS;gBACT,UAAU,EAAE,GAAG;gBACf,UAAU,EAAE,GAAG;gBACf,SAAS,EAAE,QAAQ;gBACnB,UAAU,EAAE,KAAK;gBACjB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC,QAAQ,CAAC;gBAChB,QAAQ,EAAE,EAAE;gBACZ,mBAAmB,EAAE,MAAM;aAC5B,CAAC,CAAC;YACH,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;aACzD,CAAC;QACJ,CAAC;QAED,qEAAqE;QACrE,8DAA8D;QAC9D,MAAM,WAAW,GAAG,MAAM,WAAW,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B;YACE,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,cAAc,EAAE,MAAM;SACvB,EACD;YACE,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,UAAU;YACrB,IAAI,EAAE,UAAU;SACjB,CACF,CAAC;QACF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,eAAe,MAAM,CAAC,YAAY,WAAW,MAAM,CAAC,eAAe,cAAc,MAAM,CAAC,YAAY,SAAS;iBACpH;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,iBAAiB;IACjB,MAAM,CAAC,IAAI,CACT,cAAc,EACd,yKAAyK,EACzK;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAC1D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;KAClE,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;QACzB,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAC5B,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,EACxD;YACE,KAAK;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,KAAK,IAAI,EAAE;SACnB,CACF,CAAC;QAEF,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE,CAAC;QAC9E,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACZ,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;iBACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;iBACxB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,IAAK,CAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;iBACxE,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACjG,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,SAAS,OAAO,CAAC,OAAO,CAAC,MAAM,cAAc,OAAO,CAAC,UAAU,WAAW,IAAI,EAAE;iBACvF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,iFAAiF,EACjF;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QACtD,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,MAAM,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,EAAE;YACT,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB;YAChE,cAAc,EAAE,CAAC;SAClB,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,sBAAsB,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE;aAC1F;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,gBAAgB;IAChB,MAAM,CAAC,IAAI,CACT,aAAa,EACb,yEAAyE,EACzE,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAChD,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAC5D,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE5E,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,2BAA2B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,iBAAiB,QAAQ,CAAC,MAAM,EAAE;iBAC9G;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"local-server.js","sourceRoot":"","sources":["../src/local-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2BxB,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,0CAA0C;AACzE,MAAM,eAAe,GAAG,CAAC,CAAC,CAAK,yBAAyB;AAExD,qFAAqF;AACrF,IAAI,eAAe,GAA4D,IAAI,CAAC;AACpF,SAAS,iBAAiB;IACxB,IAAI,CAAC,eAAe;QAAE,eAAe,GAAG,IAAI,GAAG,EAAE,CAAC;IAClD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,kEAAkE;AAClE,MAAM,qBAAqB,GAAG;IAC5B,KAAK,CAAC,GAAG,CAAI,GAAW;QACtB,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,kBAAkB;QAClB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;YACpC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC,SAAyB,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,KAAQ;QAChC,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;QAClC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,KAA4B,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5E,4DAA4D;QAC5D,IAAI,KAAK,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACpF,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM;gBAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,GAAW,IAAmB,iBAAiB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,KAAsB,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3C,KAAK,CAAC,MAAM,KAAmB,CAAC;IAChC,KAAK,CAAC,IAAI,KAAuB,OAAO,IAAI,CAAC,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,MAAyB;IACzD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;QAChB,YAAY,EAAE;;;;;;gIAM8G;KAC7H,CAAC,CAAC;IAEH,wDAAwD;IACxD,IAAI,OAAO,GAAwE,IAAI,CAAC;IACxF,IAAI,SAAS,GAA0F,IAAI,CAAC;IAC5G,IAAI,yBAAyB,GAA0F,IAAI,CAAC;IAE5H,KAAK,UAAU,SAAS;QACtB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,sCAAsC,CAAC,CAAC;YACjE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC;QACvB,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,UAAU,WAAW;QACxB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,yCAAyC,CAAC,CAAC;YACpE,SAAS,GAAG,GAAG,CAAC,qBAAqB,CAAC;QACxC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,UAAU,iBAAiB;QAC9B,IAAI,CAAC,yBAAyB,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,sCAAsC,CAAC,CAAC;YACjE,yBAAyB,GAAG,GAAG,CAAC,wBAAwB,CAAC;QAC3D,CAAC;QACD,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAED,8EAA8E;IAC9E,2DAA2D;IAC3D,8EAA8E;IAC9E,MAAM,cAAc,GAAG,IAAI,GAAG,EAAyB,CAAC;IAExD,+CAA+C;IAC/C,SAAS,SAAS;QAChB,OAAO,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;IAChE,CAAC;IAED,oFAAoF;IACpF,KAAK,UAAU,WAAW,CAAC,GAAW;QACpC,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE9C,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;QAChC,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7B,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,CAAC;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE1C,OAAO,CAAC,KAAK,CAAC,oCAAoC,QAAQ,CAAC,MAAM,wBAAwB,SAAS,EAAE,CAAC,CAAC;QAEtG,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,WAAW,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B;gBACE,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,cAAc,EAAE,MAAM,CAAC,cAAc;gBACrC,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,cAAc,EAAE,MAAM;gBACtB,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;aAC5C,EACD;gBACE,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,SAAS;gBACT,SAAS,EAAE,UAAU;gBACrB,IAAI,EAAE,QAAQ;aACf,CACF,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,+BAA+B,MAAM,CAAC,YAAY,WAAW,MAAM,CAAC,eAAe,cAAc,MAAM,CAAC,YAAY,QAAQ,CAAC,CAAC;QAC9I,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,0FAA0F;IAC1F,SAAS,aAAa,CAAC,GAAW;QAChC,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YAAE,OAAO;QAEjB,2BAA2B;QAC3B,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7B,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,CAAC;QAED,sCAAsC;QACtC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,eAAe,EAAE,CAAC;YAC3C,KAAK,WAAW,CAAC,GAAG,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,qCAAqC;QACrC,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;YAC/B,KAAK,WAAW,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC,EAAE,cAAc,CAAC,CAAC;IACrB,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,oSAAoS,EACpS;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC3D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;KAC7E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC;QAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC,EAAE,CAAC;QAC1F,CAAC;QAED,gCAAgC;QAChC,wEAAwE;QACxE,6EAA6E;QAC7E,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;QACxB,IAAI,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,4BAA4B;YAC5B,IAAI,SAAiB,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,iBAAiB,EAAE,CAAC;gBAC9C,wEAAwE;gBACxE,iEAAiE;gBACjE,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBACxE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,YAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;gBACxG,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC;YACzB,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,uDAAuD,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;gBAC5F,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YAClC,CAAC;YAED,GAAG,GAAG;gBACJ,SAAS;gBACT,QAAQ,EAAE,EAAE;gBACZ,YAAY,EAAE,IAAI,IAAI,EAAE;gBACxB,UAAU,EAAE,IAAI;aACjB,CAAC;YACF,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC;QAED,qBAAqB;QACrB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9B,GAAG,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC;QAE9B,+EAA+E;QAC/E,gEAAgE;QAChE,iEAAiE;QACjE,2EAA2E;QAC3E,aAAa,CAAC,GAAG,CAAC,CAAC;QAEnB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QACpC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,aAAa,OAAO,IAAI,eAAe,kDAAkD,EAAE,CAAC;SACtI,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,gBAAgB;IAChB,MAAM,CAAC,IAAI,CACT,aAAa,EACb,2IAA2I,EAC3I,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC,EAAE,CAAC;QAC1F,CAAC;QACD,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QAClC,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,WAAW,KAAK,0CAA0C,EAAE,CAAC;SACvG,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,iBAAiB;IACjB,MAAM,CAAC,IAAI,CACT,cAAc,EACd,qTAAqT,EACrT;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAC1D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;KAClE,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;QACzB,4DAA4D;QAC5D,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAC5B,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,qBAA4B,EAAE,EAC7F;YACE,KAAK;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,KAAK,IAAI,EAAE;SACnB,CACF,CAAC;QAEF,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE,CAAC;QAC9E,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,SAAS,GAAa,EAAE,CAAC;YAC/B,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS;gBAAE,SAAS,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YACxG,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY;gBAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5G,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;iBACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;iBACxB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,IAAK,CAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;iBACxE,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,IAAI,IAAI,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;YACjH,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACvB,IAAI,IAAI,sBAAsB,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrD,CAAC;YACD,IAAI,IAAI,OAAO,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,SAAS,OAAO,CAAC,OAAO,CAAC,MAAM,cAAc,OAAO,CAAC,UAAU,WAAW,IAAI,EAAE;iBACvF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,iFAAiF,EACjF;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QACtD,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,MAAM,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,EAAE;YACT,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB;YAChE,cAAc,EAAE,CAAC;SAClB,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,sBAAsB,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE;aAC1F;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,gBAAgB;IAChB,MAAM,CAAC,IAAI,CACT,aAAa,EACb,yEAAyE,EACzE,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAChD,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAC5D,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAE1F,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,2BAA2B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,iBAAiB,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE;iBAC/I;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steno-ai/mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "MCP server for Claude Code, Claude Desktop, and other MCP clients",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,7 +9,7 @@
9
9
  "directory": "packages/mcp-server"
10
10
  },
11
11
  "type": "module",
12
- "bin": { "steno-mcp": "./dist/index.js" },
12
+ "bin": { "steno-mcp": "./dist/cli.js" },
13
13
  "exports": {
14
14
  ".": {
15
15
  "import": "./dist/index.js",
@@ -27,6 +27,9 @@
27
27
  "dependencies": {
28
28
  "@modelcontextprotocol/sdk": "^1",
29
29
  "@steno-ai/sdk": "workspace:*",
30
+ "@steno-ai/engine": "workspace:*",
31
+ "@steno-ai/supabase-adapter": "workspace:*",
32
+ "@steno-ai/openai-adapter": "workspace:*",
30
33
  "zod": "^3.25"
31
34
  },
32
35
  "devDependencies": {
package/src/cli.ts ADDED
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Standalone Steno MCP server — installable via npx @steno-ai/mcp
4
+ *
5
+ * Required env vars:
6
+ * SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, OPENAI_API_KEY
7
+ *
8
+ * Optional:
9
+ * PERPLEXITY_API_KEY (cheaper embeddings)
10
+ * STENO_SCOPE_ID (default: "default")
11
+ */
12
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
+ import { createLocalServer } from './local-server.js';
14
+
15
+ async function main(): Promise<void> {
16
+ const supabaseUrl = process.env.SUPABASE_URL;
17
+ const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
18
+ const openaiKey = process.env.OPENAI_API_KEY;
19
+
20
+ if (!supabaseUrl || !supabaseKey) {
21
+ console.error('Error: SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY are required.\n');
22
+ process.exit(1);
23
+ }
24
+ if (!openaiKey) {
25
+ console.error('Error: OPENAI_API_KEY is required.\n');
26
+ process.exit(1);
27
+ }
28
+
29
+ // Dynamic imports — these resolve from npm packages when installed standalone
30
+ let createSupabaseClient: any, SupabaseStorageAdapter: any, OpenAILLMAdapter: any;
31
+ try {
32
+ const supa = await import('@steno-ai/supabase-adapter');
33
+ createSupabaseClient = supa.createSupabaseClient;
34
+ SupabaseStorageAdapter = supa.SupabaseStorageAdapter;
35
+ const oai = await import('@steno-ai/openai-adapter');
36
+ OpenAILLMAdapter = oai.OpenAILLMAdapter;
37
+ } catch {
38
+ // Fallback to relative imports (monorepo dev)
39
+ const supa = await import('../../supabase-adapter/src/index.js');
40
+ createSupabaseClient = supa.createSupabaseClient;
41
+ SupabaseStorageAdapter = supa.SupabaseStorageAdapter;
42
+ const oai = await import('../../openai-adapter/src/index.js');
43
+ OpenAILLMAdapter = oai.OpenAILLMAdapter;
44
+ }
45
+
46
+ const supabase = createSupabaseClient({ url: supabaseUrl, serviceRoleKey: supabaseKey });
47
+ const storage = new SupabaseStorageAdapter(supabase);
48
+ const cheapLLM = new OpenAILLMAdapter({ apiKey: openaiKey, model: 'gpt-5.4-mini' });
49
+
50
+ let embedding: any;
51
+ let embeddingModel: string;
52
+ let embeddingDim: number;
53
+
54
+ if (process.env.PERPLEXITY_API_KEY) {
55
+ try {
56
+ const { PerplexityEmbeddingAdapter } = await import('@steno-ai/engine');
57
+ embedding = new PerplexityEmbeddingAdapter({
58
+ apiKey: process.env.PERPLEXITY_API_KEY,
59
+ model: 'pplx-embed-v1-4b',
60
+ dimensions: 2000,
61
+ });
62
+ } catch {
63
+ const { PerplexityEmbeddingAdapter } = await import('../../engine/src/adapters/perplexity-embedding.js');
64
+ embedding = new PerplexityEmbeddingAdapter({
65
+ apiKey: process.env.PERPLEXITY_API_KEY,
66
+ model: 'pplx-embed-v1-4b',
67
+ dimensions: 2000,
68
+ });
69
+ }
70
+ embeddingModel = 'pplx-embed-v1-4b';
71
+ embeddingDim = 2000;
72
+ } else {
73
+ try {
74
+ const { OpenAIEmbeddingAdapter } = await import('@steno-ai/openai-adapter');
75
+ embedding = new OpenAIEmbeddingAdapter({ apiKey: openaiKey, model: 'text-embedding-3-large', dimensions: 3072 });
76
+ } catch {
77
+ const { OpenAIEmbeddingAdapter } = await import('../../openai-adapter/src/index.js');
78
+ embedding = new OpenAIEmbeddingAdapter({ apiKey: openaiKey, model: 'text-embedding-3-large', dimensions: 3072 });
79
+ }
80
+ embeddingModel = 'text-embedding-3-large';
81
+ embeddingDim = 3072;
82
+ }
83
+
84
+ const tenantId = process.env.STENO_TENANT_ID || '00000000-0000-0000-0000-000000000001';
85
+ const scopeId = process.env.STENO_SCOPE_ID || 'default';
86
+
87
+ try {
88
+ await storage.createTenant({ id: tenantId, name: 'MCP User', slug: `mcp-${Date.now()}`, plan: 'enterprise' });
89
+ } catch { /* already exists */ }
90
+
91
+ const server = createLocalServer({
92
+ storage, embedding, cheapLLM, tenantId,
93
+ scope: 'user', scopeId, embeddingModel, embeddingDim,
94
+ });
95
+
96
+ process.stdout.on('error', (err: NodeJS.ErrnoException) => {
97
+ if (err.code === 'EPIPE') return;
98
+ console.error('[steno] stdout error:', err);
99
+ });
100
+ process.stdin.on('error', (err: NodeJS.ErrnoException) => {
101
+ if (err.code === 'EPIPE') return;
102
+ console.error('[steno] stdin error:', err);
103
+ });
104
+
105
+ const transport = new StdioServerTransport();
106
+ await server.connect(transport);
107
+ console.error('[steno] MCP server started');
108
+ }
109
+
110
+ main().catch((err) => {
111
+ console.error('Fatal error:', err);
112
+ process.exit(1);
113
+ });