somamcp 1.0.10 → 1.0.12

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,2 @@
1
+ import { a as BackendSession, i as BackendFactory, n as BackendAdapter, r as BackendEvents, t as createFastMCPBackend } from "../index-BoCx9NV1.js";
2
+ export { type BackendAdapter, type BackendEvents, type BackendFactory, type BackendSession, createFastMCPBackend };
@@ -0,0 +1 @@
1
+ import{t as e}from"../backend-G2JeUHpG.js";export{e as createFastMCPBackend};
@@ -0,0 +1 @@
1
+ import{FastMCP as e,ServerState as t}from"fastmcp";const n=e=>{switch(e){case t.Running:return`running`;case t.Error:return`error`;default:return`stopped`}},r=(t,r)=>{let i=new e({...r,authenticate:t.authenticate,instructions:t.instructions,logger:t.logger,name:t.name,version:t.version});return{get serverState(){return n(i.serverState)},get sessions(){return i.sessions.map(e=>({sessionId:e.sessionId}))},addPrompt:e=>{i.addPrompt(e)},addResource:e=>{i.addResource(e)},addResourceTemplate:(...e)=>{i.addResourceTemplate(...e)},addTool:e=>{i.addTool(e)},getApp:()=>i.getApp(),on:(e,t)=>{i.on(e,t)},removePrompt:e=>i.removePrompt(e),removeResource:e=>i.removeResource(e),removeTool:e=>i.removeTool(e),start:async e=>{if(!e){await i.start();return}e.transportType===`httpStream`?await i.start({httpStream:e.httpStream,transportType:`httpStream`}):await i.start({transportType:`stdio`})},stop:()=>i.stop()}};export{r as t};
@@ -0,0 +1,220 @@
1
+ import { Hono } from "hono";
2
+
3
+ //#region src/types/core.d.ts
4
+ type SessionAuth = Record<string, unknown> | undefined;
5
+ /**
6
+ * Structural type compatible with StandardSchemaV1 (zod, valibot, etc.)
7
+ * We define this structurally to avoid a direct dependency on @standard-schema/spec.
8
+ */
9
+ type SchemaParams = {
10
+ readonly "~standard": {
11
+ readonly version: 1;
12
+ readonly vendor: string;
13
+ readonly types?: {
14
+ readonly input: unknown;
15
+ readonly output: unknown;
16
+ } | undefined;
17
+ readonly validate: (value: unknown) => {
18
+ value: unknown;
19
+ } | {
20
+ issues: ReadonlyArray<{
21
+ message: string;
22
+ }>;
23
+ } | Promise<{
24
+ value: unknown;
25
+ } | {
26
+ issues: ReadonlyArray<{
27
+ message: string;
28
+ }>;
29
+ }>;
30
+ };
31
+ };
32
+ type InferSchemaOutput<P extends SchemaParams> = NonNullable<P["~standard"]["types"]>["output"] extends infer O ? [O] extends [never] ? unknown : O : unknown;
33
+ type TextContent = {
34
+ text: string;
35
+ type: "text";
36
+ };
37
+ type ImageContent = {
38
+ data: string;
39
+ mimeType: string;
40
+ type: "image";
41
+ };
42
+ type AudioContent = {
43
+ data: string;
44
+ mimeType: string;
45
+ type: "audio";
46
+ };
47
+ type ResourceContent = {
48
+ resource: {
49
+ blob?: string;
50
+ mimeType?: string;
51
+ text?: string;
52
+ uri: string;
53
+ };
54
+ type: "resource";
55
+ };
56
+ type ResourceLink = {
57
+ mimeType?: string;
58
+ name?: string;
59
+ type: "resource_link";
60
+ uri: string;
61
+ };
62
+ type Content = AudioContent | ImageContent | ResourceContent | ResourceLink | TextContent;
63
+ type ContentResult = {
64
+ content: Content[];
65
+ isError?: boolean;
66
+ };
67
+ type Progress = {
68
+ progress: number;
69
+ total?: number;
70
+ };
71
+ type Context$1<T extends SessionAuth = SessionAuth> = {
72
+ client: {
73
+ version: unknown;
74
+ };
75
+ log: {
76
+ debug: (message: string, data?: unknown) => void;
77
+ error: (message: string, data?: unknown) => void;
78
+ info: (message: string, data?: unknown) => void;
79
+ warn: (message: string, data?: unknown) => void;
80
+ };
81
+ reportProgress: (progress: Progress) => Promise<void>;
82
+ requestId?: string;
83
+ session: T | undefined;
84
+ sessionId?: string;
85
+ streamContent: (content: Content | Content[]) => Promise<void>;
86
+ };
87
+ type ToolAnnotations = {
88
+ destructiveHint?: boolean;
89
+ idempotentHint?: boolean;
90
+ openWorldHint?: boolean;
91
+ readOnlyHint?: boolean;
92
+ streamingHint?: boolean;
93
+ title?: string;
94
+ };
95
+ type Tool<T extends SessionAuth = SessionAuth, P extends SchemaParams = SchemaParams> = {
96
+ _meta?: {
97
+ [key: string]: unknown;
98
+ ui?: {
99
+ resourceUri?: string;
100
+ };
101
+ };
102
+ annotations?: ToolAnnotations;
103
+ canAccess?: (auth: T) => boolean;
104
+ description?: string;
105
+ execute: (args: InferSchemaOutput<P>, context: Context$1<T>) => Promise<Content | ContentResult | string | void>;
106
+ name: string;
107
+ outputSchema?: SchemaParams;
108
+ parameters?: P;
109
+ timeoutMs?: number;
110
+ };
111
+ type Completion = {
112
+ hasMore?: boolean;
113
+ total?: number;
114
+ values: string[];
115
+ };
116
+ type ResourceResult = {
117
+ blob: string;
118
+ mimeType?: string;
119
+ uri?: string;
120
+ } | {
121
+ mimeType?: string;
122
+ text: string;
123
+ uri?: string;
124
+ };
125
+ type Resource<T extends SessionAuth = SessionAuth> = {
126
+ complete?: (name: string, value: string, auth?: T) => Promise<Completion>;
127
+ description?: string;
128
+ load: (auth?: T) => Promise<ResourceResult | ResourceResult[]>;
129
+ mimeType?: string;
130
+ name: string;
131
+ uri: string;
132
+ };
133
+ type PromptArgument<T extends SessionAuth = SessionAuth> = Readonly<{
134
+ complete?: (value: string, auth?: T) => Promise<Completion>;
135
+ description?: string;
136
+ enum?: string[];
137
+ name: string;
138
+ required?: boolean;
139
+ }>;
140
+ type PromptResult = {
141
+ messages: unknown[];
142
+ } | string;
143
+ type Prompt<T extends SessionAuth = SessionAuth, Args extends PromptArgument<T>[] = PromptArgument<T>[]> = {
144
+ arguments?: Args;
145
+ complete?: (name: string, value: string, auth?: T) => Promise<Completion>;
146
+ description?: string;
147
+ load: (args: Record<string, string | undefined>, auth?: T) => Promise<PromptResult>;
148
+ name: string;
149
+ };
150
+ type ServerStatus = "error" | "running" | "stopped";
151
+ declare class UserError extends Error {
152
+ constructor(message: string);
153
+ }
154
+ //#endregion
155
+ //#region src/types/server.d.ts
156
+ type Logger = {
157
+ debug: (...args: unknown[]) => void;
158
+ error: (...args: unknown[]) => void;
159
+ info: (...args: unknown[]) => void;
160
+ log: (...args: unknown[]) => void;
161
+ warn: (...args: unknown[]) => void;
162
+ };
163
+ type ServerConfig<T extends SessionAuth = SessionAuth> = {
164
+ authenticate?: (request: unknown) => Promise<T>;
165
+ instructions?: string;
166
+ logger?: Logger;
167
+ name: string;
168
+ version: `${number}.${number}.${number}`;
169
+ };
170
+ type TransportConfig = {
171
+ transportType: "stdio";
172
+ } | {
173
+ httpStream: {
174
+ enableJsonResponse?: boolean;
175
+ endpoint?: `/${string}`;
176
+ host?: string;
177
+ port: number;
178
+ };
179
+ transportType: "httpStream";
180
+ };
181
+ //#endregion
182
+ //#region src/backend/adapter.d.ts
183
+ type BackendSession<T extends SessionAuth = SessionAuth> = {
184
+ sessionId?: string;
185
+ auth?: T;
186
+ };
187
+ type BackendEvents<T extends SessionAuth> = {
188
+ connect: (event: {
189
+ session: BackendSession<T>;
190
+ }) => void;
191
+ disconnect: (event: {
192
+ session: BackendSession<T>;
193
+ }) => void;
194
+ };
195
+ type BackendAdapter<T extends SessionAuth = SessionAuth> = {
196
+ readonly serverState: ServerStatus;
197
+ readonly sessions: ReadonlyArray<BackendSession<T>>;
198
+ addPrompt: <Args extends PromptArgument<T>[]>(prompt: Prompt<T, Args>) => void;
199
+ addResource: (resource: Resource<T>) => void;
200
+ addResourceTemplate: (...args: ReadonlyArray<unknown>) => void;
201
+ addTool: <P extends SchemaParams>(tool: Tool<T, P>) => void;
202
+ getApp: () => Hono;
203
+ on: <E extends keyof BackendEvents<T>>(event: E, handler: BackendEvents<T>[E]) => void;
204
+ removePrompt: (name: string) => void;
205
+ removeResource: (name: string) => void;
206
+ removeTool: (name: string) => void;
207
+ start: (transport?: TransportConfig) => Promise<void>;
208
+ stop: () => Promise<void>;
209
+ };
210
+ type BackendFactory<T extends SessionAuth = SessionAuth> = (config: {
211
+ authenticate?: (request: unknown) => Promise<T>;
212
+ instructions?: string;
213
+ name: string;
214
+ version: `${number}.${number}.${number}`;
215
+ }, backendOptions?: Record<string, unknown>) => BackendAdapter<T>;
216
+ //#endregion
217
+ //#region src/backend/fastmcp.d.ts
218
+ declare const createFastMCPBackend: <T extends SessionAuth = SessionAuth>(config: ServerConfig<T>, backendOptions?: Record<string, unknown>) => BackendAdapter<T>;
219
+ //#endregion
220
+ export { UserError as A, ResourceResult as C, TextContent as D, SessionAuth as E, Tool as O, ResourceLink as S, ServerStatus as T, Prompt as _, BackendSession as a, Resource as b, TransportConfig as c, Content as d, ContentResult as f, Progress as g, InferSchemaOutput as h, BackendFactory as i, ToolAnnotations as k, AudioContent as l, ImageContent as m, BackendAdapter as n, Logger as o, Context$1 as p, BackendEvents as r, ServerConfig as s, createFastMCPBackend as t, Completion as u, PromptArgument as v, SchemaParams as w, ResourceContent as x, PromptResult as y };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { A as UserError, C as ResourceResult, D as TextContent, E as SessionAuth, O as Tool, S as ResourceLink, T as ServerStatus, _ as Prompt, a as BackendSession, b as Resource, c as TransportConfig, d as Content, f as ContentResult, g as Progress, h as InferSchemaOutput, i as BackendFactory, k as ToolAnnotations, l as AudioContent, m as ImageContent, n as BackendAdapter, o as Logger, p as Context, s as ServerConfig, t as createFastMCPBackend, u as Completion, v as PromptArgument, w as SchemaParams, x as ResourceContent, y as PromptResult } from "./index-BoCx9NV1.js";
1
2
  import { Option } from "functype";
2
3
  import { DirectLogger, DirectLogger as DirectLogger$1 } from "functype-log";
3
4
  import { z } from "zod";
@@ -27,220 +28,6 @@ type DirectoryArtifact = ArtifactCommon & {
27
28
  type ArtifactConfig = DirectoryArtifact | DynamicArtifact | StaticArtifact;
28
29
  type ArtifactAuthenticate = (request: unknown) => Promise<unknown>;
29
30
  //#endregion
30
- //#region src/types/core.d.ts
31
- type SessionAuth = Record<string, unknown> | undefined;
32
- /**
33
- * Structural type compatible with StandardSchemaV1 (zod, valibot, etc.)
34
- * We define this structurally to avoid a direct dependency on @standard-schema/spec.
35
- */
36
- type SchemaParams = {
37
- readonly "~standard": {
38
- readonly version: 1;
39
- readonly vendor: string;
40
- readonly types?: {
41
- readonly input: unknown;
42
- readonly output: unknown;
43
- } | undefined;
44
- readonly validate: (value: unknown) => {
45
- value: unknown;
46
- } | {
47
- issues: ReadonlyArray<{
48
- message: string;
49
- }>;
50
- } | Promise<{
51
- value: unknown;
52
- } | {
53
- issues: ReadonlyArray<{
54
- message: string;
55
- }>;
56
- }>;
57
- };
58
- };
59
- type InferSchemaOutput<P extends SchemaParams> = NonNullable<P["~standard"]["types"]>["output"] extends infer O ? [O] extends [never] ? unknown : O : unknown;
60
- type TextContent = {
61
- text: string;
62
- type: "text";
63
- };
64
- type ImageContent = {
65
- data: string;
66
- mimeType: string;
67
- type: "image";
68
- };
69
- type AudioContent = {
70
- data: string;
71
- mimeType: string;
72
- type: "audio";
73
- };
74
- type ResourceContent = {
75
- resource: {
76
- blob?: string;
77
- mimeType?: string;
78
- text?: string;
79
- uri: string;
80
- };
81
- type: "resource";
82
- };
83
- type ResourceLink = {
84
- mimeType?: string;
85
- name?: string;
86
- type: "resource_link";
87
- uri: string;
88
- };
89
- type Content = AudioContent | ImageContent | ResourceContent | ResourceLink | TextContent;
90
- type ContentResult = {
91
- content: Content[];
92
- isError?: boolean;
93
- };
94
- type Progress = {
95
- progress: number;
96
- total?: number;
97
- };
98
- type Context<T extends SessionAuth = SessionAuth> = {
99
- client: {
100
- version: unknown;
101
- };
102
- log: {
103
- debug: (message: string, data?: unknown) => void;
104
- error: (message: string, data?: unknown) => void;
105
- info: (message: string, data?: unknown) => void;
106
- warn: (message: string, data?: unknown) => void;
107
- };
108
- reportProgress: (progress: Progress) => Promise<void>;
109
- requestId?: string;
110
- session: T | undefined;
111
- sessionId?: string;
112
- streamContent: (content: Content | Content[]) => Promise<void>;
113
- };
114
- type ToolAnnotations = {
115
- destructiveHint?: boolean;
116
- idempotentHint?: boolean;
117
- openWorldHint?: boolean;
118
- readOnlyHint?: boolean;
119
- streamingHint?: boolean;
120
- title?: string;
121
- };
122
- type Tool<T extends SessionAuth = SessionAuth, P extends SchemaParams = SchemaParams> = {
123
- _meta?: {
124
- [key: string]: unknown;
125
- ui?: {
126
- resourceUri?: string;
127
- };
128
- };
129
- annotations?: ToolAnnotations;
130
- canAccess?: (auth: T) => boolean;
131
- description?: string;
132
- execute: (args: InferSchemaOutput<P>, context: Context<T>) => Promise<Content | ContentResult | string | void>;
133
- name: string;
134
- outputSchema?: SchemaParams;
135
- parameters?: P;
136
- timeoutMs?: number;
137
- };
138
- type Completion = {
139
- hasMore?: boolean;
140
- total?: number;
141
- values: string[];
142
- };
143
- type ResourceResult = {
144
- blob: string;
145
- mimeType?: string;
146
- uri?: string;
147
- } | {
148
- mimeType?: string;
149
- text: string;
150
- uri?: string;
151
- };
152
- type Resource<T extends SessionAuth = SessionAuth> = {
153
- complete?: (name: string, value: string, auth?: T) => Promise<Completion>;
154
- description?: string;
155
- load: (auth?: T) => Promise<ResourceResult | ResourceResult[]>;
156
- mimeType?: string;
157
- name: string;
158
- uri: string;
159
- };
160
- type PromptArgument<T extends SessionAuth = SessionAuth> = Readonly<{
161
- complete?: (value: string, auth?: T) => Promise<Completion>;
162
- description?: string;
163
- enum?: string[];
164
- name: string;
165
- required?: boolean;
166
- }>;
167
- type PromptResult = {
168
- messages: unknown[];
169
- } | string;
170
- type Prompt<T extends SessionAuth = SessionAuth, Args extends PromptArgument<T>[] = PromptArgument<T>[]> = {
171
- arguments?: Args;
172
- complete?: (name: string, value: string, auth?: T) => Promise<Completion>;
173
- description?: string;
174
- load: (args: Record<string, string | undefined>, auth?: T) => Promise<PromptResult>;
175
- name: string;
176
- };
177
- type ServerStatus = "error" | "running" | "stopped";
178
- declare class UserError extends Error {
179
- constructor(message: string);
180
- }
181
- //#endregion
182
- //#region src/types/server.d.ts
183
- type Logger = {
184
- debug: (...args: unknown[]) => void;
185
- error: (...args: unknown[]) => void;
186
- info: (...args: unknown[]) => void;
187
- log: (...args: unknown[]) => void;
188
- warn: (...args: unknown[]) => void;
189
- };
190
- type ServerConfig<T extends SessionAuth = SessionAuth> = {
191
- authenticate?: (request: unknown) => Promise<T>;
192
- instructions?: string;
193
- logger?: Logger;
194
- name: string;
195
- version: `${number}.${number}.${number}`;
196
- };
197
- type TransportConfig = {
198
- transportType: "stdio";
199
- } | {
200
- httpStream: {
201
- enableJsonResponse?: boolean;
202
- endpoint?: `/${string}`;
203
- host?: string;
204
- port: number;
205
- };
206
- transportType: "httpStream";
207
- };
208
- //#endregion
209
- //#region src/backend/adapter.d.ts
210
- type BackendSession<T extends SessionAuth = SessionAuth> = {
211
- sessionId?: string;
212
- auth?: T;
213
- };
214
- type BackendEvents<T extends SessionAuth> = {
215
- connect: (event: {
216
- session: BackendSession<T>;
217
- }) => void;
218
- disconnect: (event: {
219
- session: BackendSession<T>;
220
- }) => void;
221
- };
222
- type BackendAdapter<T extends SessionAuth = SessionAuth> = {
223
- readonly serverState: ServerStatus;
224
- readonly sessions: ReadonlyArray<BackendSession<T>>;
225
- addPrompt: <Args extends PromptArgument<T>[]>(prompt: Prompt<T, Args>) => void;
226
- addResource: (resource: Resource<T>) => void;
227
- addResourceTemplate: (...args: ReadonlyArray<unknown>) => void;
228
- addTool: <P extends SchemaParams>(tool: Tool<T, P>) => void;
229
- getApp: () => Hono;
230
- on: <E extends keyof BackendEvents<T>>(event: E, handler: BackendEvents<T>[E]) => void;
231
- removePrompt: (name: string) => void;
232
- removeResource: (name: string) => void;
233
- removeTool: (name: string) => void;
234
- start: (transport?: TransportConfig) => Promise<void>;
235
- stop: () => Promise<void>;
236
- };
237
- type BackendFactory<T extends SessionAuth = SessionAuth> = (config: {
238
- authenticate?: (request: unknown) => Promise<T>;
239
- instructions?: string;
240
- name: string;
241
- version: `${number}.${number}.${number}`;
242
- }, backendOptions?: Record<string, unknown>) => BackendAdapter<T>;
243
- //#endregion
244
31
  //#region src/buildInfo.d.ts
245
32
  type BuildInfo = {
246
33
  branch?: string;
@@ -422,9 +209,6 @@ type ContentInput = {
422
209
  declare const imageContent: (input: ContentInput) => Promise<ImageContent>;
423
210
  declare const audioContent: (input: ContentInput) => Promise<AudioContent>;
424
211
  //#endregion
425
- //#region src/backend/fastmcp.d.ts
426
- declare const createFastMCPBackend: <T extends SessionAuth = SessionAuth>(config: ServerConfig<T>, backendOptions?: Record<string, unknown>) => BackendAdapter<T>;
427
- //#endregion
428
212
  //#region src/telemetry/CompositeTelemetry.d.ts
429
213
  declare const createCompositeTelemetry: (collectors: ReadonlyArray<TelemetryCollector>) => TelemetryCollector;
430
214
  //#endregion
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{Option as e,Ref as t,Try as n}from"functype";import{FastMCP as r,ServerState as i}from"fastmcp";import{Client as a}from"@modelcontextprotocol/sdk/client/index.js";import{StreamableHTTPClientTransport as o}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{createDirectConsoleLogger as s}from"functype-log";import{appendFile as c,mkdir as l,readFile as u}from"node:fs/promises";import{dirname as d,extname as f}from"node:path";import{z as p}from"zod";const m=e=>e.json({error:`Unauthorized`},401),h=e=>async(t,n)=>{if(!e)return m(t);try{await e(t.env?.incoming??t.req.raw)}catch{return m(t)}await n()},g=(e,t,n)=>{t.forEach(t=>{switch(t.protected&&e.use(t.path,h(n)),t.type){case`static`:e.get(t.path,e=>e.body(t.content,{headers:{"Content-Type":t.contentType}}));break;case`dynamic`:e.get(t.path,e=>t.handler(e));break;case`directory`:break}})},_=(e,t,n)=>({handler:()=>{let r=v(e(),t(),n());return new Response(r,{headers:{"Content-Type":`text/html; charset=utf-8`}})},path:`/dashboard`,protected:!0,type:`dynamic`}),v=(e,t,n)=>`<!DOCTYPE html>
1
+ import{t as e}from"./backend-G2JeUHpG.js";import{Option as t,Ref as n,Try as r}from"functype";import{Client as i}from"@modelcontextprotocol/sdk/client/index.js";import{StreamableHTTPClientTransport as a}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{createDirectConsoleLogger as o}from"functype-log";import{appendFile as s,mkdir as c,readFile as l}from"node:fs/promises";import{dirname as u,extname as d}from"node:path";import{z as f}from"zod";const p=e=>e.json({error:`Unauthorized`},401),m=e=>async(t,n)=>{if(!e)return p(t);try{await e(t.env?.incoming??t.req.raw)}catch{return p(t)}await n()},h=(e,t,n)=>{t.forEach(t=>{switch(t.protected&&e.use(t.path,m(n)),t.type){case`static`:e.get(t.path,e=>e.body(t.content,{headers:{"Content-Type":t.contentType}}));break;case`dynamic`:e.get(t.path,e=>t.handler(e));break;case`directory`:break}})},g=(e,t,n)=>({handler:()=>{let r=_(e(),t(),n());return new Response(r,{headers:{"Content-Type":`text/html; charset=utf-8`}})},path:`/dashboard`,protected:!0,type:`dynamic`}),_=(e,t,n)=>`<!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8">
@@ -32,7 +32,7 @@ import{Option as e,Ref as t,Try as n}from"functype";import{FastMCP as r,ServerSt
32
32
  <div class="card">
33
33
  <h2>Health</h2>
34
34
  <div class="metric"><span class="metric-label">Status:</span> <span class="status ${e.status}">${e.status}</span></div>
35
- <div class="metric"><span class="metric-label">Uptime:</span> <span class="metric-value">${y(e.uptime)}</span></div>
35
+ <div class="metric"><span class="metric-label">Uptime:</span> <span class="metric-value">${v(e.uptime)}</span></div>
36
36
  <div class="metric"><span class="metric-label">Sessions:</span> <span class="metric-value">${e.activeSessions}</span></div>
37
37
  <div class="metric"><span class="metric-label">Gateways:</span> <span class="metric-value">${e.gateways.connected}/${e.gateways.total}</span></div>
38
38
  </div>
@@ -54,9 +54,9 @@ import{Option as e,Ref as t,Try as n}from"functype";import{FastMCP as r,ServerSt
54
54
  </div>`:``}
55
55
  </div>
56
56
  </body>
57
- </html>`,y=e=>{let t=Math.floor(e/1e3),n=Math.floor(t/60),r=Math.floor(n/60),i=Math.floor(r/24);return i>0?`${String(i)}d ${String(r%24)}h`:r>0?`${String(r)}h ${String(n%60)}m`:n>0?`${String(n)}m ${String(t%60)}s`:`${String(t)}s`},b=`/health`,x=`/health/detail`,S=(e,t=b)=>({handler:()=>{let t=e(),n=t.status===`running`?200:503;return new Response(JSON.stringify({name:t.name,status:t.status}),{headers:{"Content-Type":`application/json`},status:n})},path:t,type:`dynamic`}),C=(e,t=x)=>({handler:()=>{let t=e(),n=t.status===`running`?200:503;return new Response(JSON.stringify(t),{headers:{"Content-Type":`application/json`},status:n})},path:t,protected:!0,type:`dynamic`}),w=`/info`,T=(e,t=w)=>({handler:()=>new Response(JSON.stringify(e()),{headers:{"Content-Type":`application/json`},status:200}),path:t,protected:!0,type:`dynamic`}),ee=e=>{switch(e){case i.Running:return`running`;case i.Error:return`error`;default:return`stopped`}},E=(e,t)=>{let n=new r({...t,authenticate:e.authenticate,instructions:e.instructions,logger:e.logger,name:e.name,version:e.version});return{get serverState(){return ee(n.serverState)},get sessions(){return n.sessions.map(e=>({sessionId:e.sessionId}))},addPrompt:e=>{n.addPrompt(e)},addResource:e=>{n.addResource(e)},addResourceTemplate:(...e)=>{n.addResourceTemplate(...e)},addTool:e=>{n.addTool(e)},getApp:()=>n.getApp(),on:(e,t)=>{n.on(e,t)},removePrompt:e=>n.removePrompt(e),removeResource:e=>n.removeResource(e),removeTool:e=>n.removeTool(e),start:async e=>{if(!e){await n.start();return}e.transportType===`httpStream`?await n.start({httpStream:e.httpStream,transportType:`httpStream`}):await n.start({transportType:`stdio`})},stop:()=>n.stop()}},D=e=>{let t=process.env[e];return t&&t.length>0?t:void 0},O=()=>({branch:D(`SOMAMCP_BUILD_BRANCH`),commit:D(`SOMAMCP_BUILD_COMMIT`),date:D(`SOMAMCP_BUILD_DATE`),environment:D(`SOMAMCP_ENVIRONMENT`)}),k=e=>{let t=O();return{branch:e?.branch??t.branch,commit:e?.commit??t.commit,date:e?.date??t.date,environment:e?.environment??t.environment}},te=()=>({arch:process.arch,nodeVersion:process.version,platform:process.platform}),A=(r,i)=>{let s=t(e.none()),c=t(e.none()),l=t([]),u=t(`disconnected`),d=t(e.none()),f=r.name??r.id,p=()=>{let t=r.reconnectIntervalMs??5e3;d.set(e(setTimeout(()=>{m.connect()},t)))},m={get config(){return r},get info(){return{id:r.id,name:f,remoteTools:l.get().map(e=>({description:e.description,name:e.name})),status:u.get(),url:r.url}},get name(){return f},get status(){return u.get()},get tools(){return l.get()},async callTool(e,t={}){let n=s.get();if(n.isEmpty||u.get()!==`connected`)throw Error(`Gateway ${r.id} is not connected`);return n.orThrow(Error(`Gateway ${r.id} is not connected`)).callTool({arguments:t,name:e})},async connect(){if(u.get()===`connected`)return;u.set(`connecting`);let t=Date.now();(await n.fromPromise((async()=>{let t=new o(new URL(r.url));c.set(e(t));let n=new a({name:`soma-gateway-${r.id}`,version:`1.0.0`});s.set(e(n)),await n.connect(t);let i=await n.listTools();l.set(i.tools)})())).fold(e=>{u.set(`error`),i.recordEvent({data:{id:r.id,url:r.url},error:e instanceof Error?e.message:String(e),name:f,timestamp:t,type:`gateway.error`}),r.reconnect!==!1&&p()},()=>{u.set(`connected`),i.recordEvent({data:{id:r.id,remoteToolCount:l.get().length,url:r.url},durationMs:Date.now()-t,name:f,timestamp:t,type:`gateway.connect`})})},async disconnect(){d.get().match({None:()=>void 0,Some:e=>clearTimeout(e)}),d.set(e.none());let t=s.get();t.isSome()&&await n.fromPromise(t.value.close()),s.set(e.none()),c.set(e.none()),l.set([]),u.set(`disconnected`),i.recordEvent({data:{id:r.id},name:f,timestamp:Date.now(),type:`gateway.disconnect`})}};return m},j=t=>{let n=new Map;return{get connectedCount(){return[...n.values()].filter(e=>e.status===`connected`).length},get totalCount(){return n.size},add(e){let r=A(e,t);return n.set(e.id,r),r},async connectAll(){await Promise.allSettled([...n.values()].map(e=>e.connect()))},async disconnectAll(){await Promise.allSettled([...n.values()].map(e=>e.disconnect()))},get(t){return e(n.get(t))},getAll(){return[...n.values()]},getInfoAll(){return[...n.values()].map(e=>e.info)}}},M=e=>({flush:async()=>{await Promise.all(e.map(e=>e.flush?e.flush():Promise.resolve()))},recordEvent:t=>{e.forEach(e=>e.recordEvent(t))}}),N=e=>({flush:()=>Promise.resolve(),recordEvent:t=>{let n={durationMs:t.durationMs,eventName:t.name,timestamp:new Date(t.timestamp).toISOString(),type:t.type,...t.sessionId&&{sessionId:t.sessionId},...t.requestId&&{requestId:t.requestId},...t.errorCategory&&{errorCategory:t.errorCategory},...t.data};t.error?e.withError(Error(t.error)).error(t.type,n):e.info(t.type,n)}}),P=(e=`[soma]`)=>N(s({prefix:e,stream:`stderr`})),F=e=>{if(e instanceof Error){let t=e.message.toLowerCase();if(t.includes(`validation`)||t.includes(`invalid`)||t.includes(`schema`))return`validation`;if(t.includes(`timeout`)||t.includes(`timed out`)||t.includes(`etimedout`))return`timeout`;if(t.includes(`gateway`)||t.includes(`not connected`)||t.includes(`econnrefused`)||t.includes(`connection refused`))return`gateway`;if(t.includes(`auth`)||t.includes(`unauthorized`)||t.includes(`forbidden`))return`auth`;if(t.includes(`not found`)||t.includes(`404`))return`not_found`}return typeof e==`object`&&e&&`name`in e&&e.name===`UserError`?`validation`:`internal`},I=(e,t)=>{switch(e){case`validation`:return[`Check the tool's parameter schema and provide valid input`];case`timeout`:return[`The operation timed out. Try again or reduce the scope of the request`];case`gateway`:return[`Gateway is ${t?.gatewayStatus??`unavailable`}. The remote service may be down`,`Try again later or check the remote service status`];case`auth`:return[`Authentication failed. Check credentials or permissions`];case`not_found`:return[`The requested resource was not found. Verify the identifier`];case`internal`:return[`An internal error occurred. The tool maintainer should investigate`]}},L=(e,t)=>{let n=F(e),r=e instanceof Error?e.message:String(e),i=I(n,t),a={...t?.gatewayStatus&&{gatewayStatus:t.gatewayStatus},...t?.toolName&&{toolName:t.toolName}};return{errorCategory:n,message:r,...Object.keys(a).length>0&&{relatedState:a},suggestions:i}},R=n=>{let r=t([]),i=t(e.none()),a=t(!1),o=async()=>{let e=r.getAndSet([]);if(e.length===0)return;a.get()||(await l(d(n.filePath),{recursive:!0}),a.set(!0));let t=`${e.map(e=>JSON.stringify(e)).join(`
58
- `)}\n`;await c(n.filePath,t)},s=()=>{i.get().isSome()||i.set(e(setTimeout(()=>{i.set(e.none()),o()},n.flushIntervalMs??1e3)))};return{flush:async()=>{i.get().match({None:()=>void 0,Some:e=>clearTimeout(e)}),i.set(e.none()),await o()},recordEvent:e=>{r.update(t=>[...t,e]),s()}}},z={flush:()=>Promise.resolve(),recordEvent:()=>{}},B=(e,t)=>!t||t.length===0?e:Object.fromEntries(Object.entries(e).map(([e,n])=>[e,t.includes(e)?`[REDACTED]`:n])),V=(e,t=1e4)=>{let n=typeof e==`string`?e:JSON.stringify(e);return n&&n.length>t?`${n.slice(0,t)}...[truncated, ${n.length} total chars]`:e},H=e=>n.fromPromise(e),U=(e,t,n)=>({...e,execute:async(r,i)=>{let a=n?.captureLevel??`full`;if(a===`none`)return e.execute(r,i);let o=Date.now(),{requestId:s,sessionId:c}=i,l=a===`full`?B(r,n?.redactInputFields):void 0;return(await H(e.execute(r,i))).fold(n=>{let r=L(n,{toolName:e.name});return t.recordEvent({data:{name:e.name},durationMs:Date.now()-o,error:r.message,errorCategory:r.errorCategory,errorStack:n.stack,input:l,name:e.name,requestId:s,sessionId:c,timestamp:o,type:`tool.error`}),{content:[{text:JSON.stringify(r,null,2),type:`text`}],isError:!0}},r=>(t.recordEvent({data:{name:e.name},durationMs:Date.now()-o,input:l,name:e.name,output:a===`full`?V(r,n?.maxOutputSize):void 0,requestId:s,sessionId:c,timestamp:o,type:`tool.execute`}),r))}}),W=(e,t)=>({...e,load:async n=>{let r=Date.now();return(await H(e.load(n))).fold(n=>{let i=L(n);throw t.recordEvent({data:{name:e.name,uri:e.uri},durationMs:Date.now()-r,error:i.message,errorCategory:i.errorCategory,errorStack:n.stack,name:e.name,timestamp:r,type:`resource.error`}),n},n=>(t.recordEvent({data:{name:e.name,uri:e.uri},durationMs:Date.now()-r,name:e.name,timestamp:r,type:`resource.load`}),n))}}),G=(e,t)=>({...e,load:async(n,r)=>{let i=Date.now();return(await H(e.load(n,r))).fold(n=>{let r=L(n);throw t.recordEvent({data:{name:e.name},durationMs:Date.now()-i,error:r.message,errorCategory:r.errorCategory,errorStack:n.stack,name:e.name,timestamp:i,type:`prompt.error`}),n},n=>(t.recordEvent({data:{name:e.name},durationMs:Date.now()-i,name:e.name,timestamp:i,type:`prompt.load`}),n))}}),K=e=>n.fromPromise(e),q=(e,t)=>{let n=e.config.toolPrefix??`${e.config.id}_`;return e.tools.map(r=>({annotations:{openWorldHint:!0,readOnlyHint:!0},description:`[${e.name}] ${r.description??`Remote tool`}`,execute:async i=>{let a=Date.now(),o=`${n}${r.name}`;return(await K(e.callTool(r.name,i))).fold(n=>{let s=L(n,{gatewayStatus:e.status,toolName:r.name});return t?.recordEvent({data:{gateway:e.config.id,remoteTool:r.name},durationMs:Date.now()-a,error:s.message,errorCategory:s.errorCategory,errorStack:n.stack,input:i,name:o,timestamp:a,type:`tool.error`}),{content:[{text:JSON.stringify(s,null,2),type:`text`}],isError:!0}},n=>(t?.recordEvent({data:{gateway:e.config.id,remoteTool:r.name},durationMs:Date.now()-a,input:i,name:o,output:n,timestamp:a,type:`tool.execute`}),JSON.stringify(n,null,2)))},name:`${n}${r.name}`}))},J=(e,t=`info`)=>({annotations:{readOnlyHint:!0},description:`Returns identity and build information for this server (name, version, build commit, runtime, capability counts)`,execute:()=>Promise.resolve(JSON.stringify(e(),null,2)),name:t}),Y=e=>{let{artifacts:n,backendOptions:r,build:i,enableDashboard:a,enableHealthEndpoint:o,enableInfoEndpoint:s,enableIntrospection:c,gateways:l,healthDetailPath:u,healthPath:d,infoPath:f,introspectionPrefix:p,logLayer:m,telemetry:h,...v}=e,y=v.name,b=v.version,x=k(i),w=te(),ee=p??``,D=h??(m?N(m):z),O=E(v,r),A=j(D),M=[],P=[],F=[],I=t(0);l?.forEach(e=>A.add(e));let L=()=>{let e=I.get(),t=e>0?Date.now()-e:0;return{activeSessions:O.sessions.length,gateways:{connected:A.connectedCount,total:A.totalCount},name:y,startedAt:e,status:O.serverState,uptime:t}},R=()=>({prompts:F,resources:P,tools:M}),B=()=>({build:x,capabilities:{prompts:F.length,resources:P.length,tools:M.length},name:y,runtime:w,version:b});c!==!1&&O.addTool(J(()=>B(),`${ee}info`));let V=[...n??[]];o!==!1&&(V.push(S(()=>L(),d)),V.push(C(()=>L(),u))),s!==!1&&V.push(T(()=>B(),f)),a!==!1&&V.push(_(()=>L(),()=>R(),()=>A.getInfoAll())),V.length>0&&g(O.getApp(),V,v.authenticate),O.on(`connect`,({session:e})=>{D.recordEvent({data:{sessionId:e.sessionId},name:y,timestamp:Date.now(),type:`session.connect`})}),O.on(`disconnect`,({session:e})=>{D.recordEvent({data:{sessionId:e.sessionId},name:y,timestamp:Date.now(),type:`session.disconnect`})});let H=e=>{let t=U(e,D,`captureConfig`in e?e.captureConfig:void 0);O.addTool(t),M.push({description:e.description,name:e.name})},K=e=>{let t=W(e,D);O.addResource(t),P.push({description:e.description,name:e.name,uri:e.uri})},Y=e=>{let t=G(e,D);O.addPrompt(t),F.push({description:e.description,name:e.name})};return{get name(){return y},get serverState(){return O.serverState},get sessions(){return O.sessions},addPrompt:Y,addPrompts:e=>{e.forEach(Y)},addResource:K,addResources:e=>{e.forEach(K)},addResourceTemplate:(...e)=>{O.addResourceTemplate(...e)},addTool:H,addTools:e=>{e.forEach(e=>H(e))},getApp:()=>O.getApp(),getCapabilities:R,getGatewayManager:()=>A,getHealth:L,getInfo:B,removePrompt:e=>{O.removePrompt(e)},removeResource:e=>{O.removeResource(e)},removeTool:e=>{O.removeTool(e)},async start(e){I.set(Date.now()),D.recordEvent({name:y,timestamp:I.get(),type:`server.start`}),await O.start(e),await A.connectAll(),A.getAll().filter(e=>e.status===`connected`&&e.config.proxyTools!==!1).forEach(e=>{q(e,D).forEach(e=>O.addTool(e))})},async stop(){await A.disconnectAll(),await O.stop(),D.recordEvent({name:y,timestamp:Date.now(),type:`server.stop`}),D.flush&&await D.flush()}}};var ne=class extends Error{constructor(e){super(e),this.name=`UserError`}};const re={".avif":`image/avif`,".bmp":`image/bmp`,".gif":`image/gif`,".ico":`image/x-icon`,".jpeg":`image/jpeg`,".jpg":`image/jpeg`,".png":`image/png`,".svg":`image/svg+xml`,".tiff":`image/tiff`,".webp":`image/webp`},ie={".aac":`audio/aac`,".flac":`audio/flac`,".m4a":`audio/mp4`,".mp3":`audio/mpeg`,".ogg":`audio/ogg`,".opus":`audio/opus`,".wav":`audio/wav`,".weba":`audio/webm`},X=(e,t,n)=>t[f(new URL(e,`file:///`).pathname).toLowerCase()]??n,Z=async(e,t)=>{if(`url`in e){let n=await fetch(e.url);if(!n.ok)throw Error(`Failed to fetch ${t} from URL (${e.url}): ${n.status} ${n.statusText}`);return{data:Buffer.from(await n.arrayBuffer()),source:e.url}}return`path`in e?{data:await u(e.path),source:e.path}:{data:e.buffer}},ae=async e=>{let{data:t,source:n}=await Z(e,`image`),r=n?X(n,re,`image/png`):`image/png`;return{data:t.toString(`base64`),mimeType:r,type:`image`}},oe=async e=>{let{data:t,source:n}=await Z(e,`audio`),r=n?X(n,ie,`audio/mpeg`):`audio/mpeg`;return{data:t.toString(`base64`),mimeType:r,type:`audio`}},se=e=>s({prefix:`[${e}]`,stream:`stderr`}).withContext({cell:e}),ce=e=>({annotations:{readOnlyHint:!0},description:`Lists all tools, resources, and prompts registered on this server`,execute:()=>Promise.resolve(JSON.stringify(e(),null,2)),name:`soma_capabilities`}),le=e=>({annotations:{readOnlyHint:!0},description:`Lists all gateway connections to remote servers with their status and available tools`,execute:()=>Promise.resolve(JSON.stringify(e(),null,2)),name:`soma_connections`}),ue=e=>({annotations:{readOnlyHint:!0},description:`Returns health and status information for this server including uptime, sessions, and gateway status`,execute:()=>Promise.resolve(JSON.stringify(e(),null,2)),name:`soma_health`}),Q=[{description:`GitHub personal access token`,name:`github_pat`,pattern:/\b(?:ghp|gho|ghu|ghs|ghr|github_pat)_[A-Za-z0-9_]{20,}\b/g},{description:`AWS access key ID`,name:`aws_access_key`,pattern:/\bAKIA[0-9A-Z]{16}\b/g},{description:`AWS secret access key (heuristic)`,name:`aws_secret_key`,pattern:/(?<![A-Za-z0-9/+])[A-Za-z0-9/+]{40}(?![A-Za-z0-9/+])/g},{description:`Stripe secret/publishable key`,name:`stripe_key`,pattern:/\b(?:sk|pk|rk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g},{description:`Slack token`,name:`slack_token`,pattern:/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g},{description:`JSON Web Token`,name:`jwt`,pattern:/\beyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]+\b/g},{description:`OpenAI / Anthropic style API key`,name:`ai_api_key`,pattern:/\b(?:sk-ant-|sk-)[A-Za-z0-9_-]{20,}\b/g},{description:`Generic bearer-style secret prefix`,name:`bearer_authorization`,pattern:/\b[Bb]earer\s+[A-Za-z0-9._\-+/]{16,}\b/g},{description:`Email address`,name:`email`,pattern:/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g},{description:`Private IPv4 address (RFC1918)`,name:`private_ipv4`,pattern:/\b(?:10(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2})\b/g},{description:`URL pointing at internal/private hostname`,name:`internal_url`,pattern:/\bhttps?:\/\/(?:[a-z0-9-]+\.)*(?:internal|intranet|corp|local|lan)(?:[/:][^\s]*)?/gi}],$=(e,t=Q)=>{let{counts:n,text:r}=t.reduce((e,t)=>{let n=Array.from(e.text.matchAll(t.pattern)).length;return n===0?e:{counts:new Map(e.counts).set(t.name,n),text:e.text.replace(t.pattern,t.replacement??`[REDACTED]`)}},{counts:new Map,text:e}),i=Array.from(n.entries()).map(([e,t])=>({count:t,name:e}));return{matches:i,redacted:i.length>0,text:r}},de=[`Submit a feedback report or issue to this server's maintainers.`,``,`IMPORTANT: Treat all input as potentially public.`,`- Do NOT include API keys, tokens, passwords, or credentials`,`- Do NOT include customer data, PII, or proprietary information`,`- Do NOT include internal URLs, hostnames, or system topology`,`- Describe the behavior and how to reproduce it, not the data involved`,``,`Common credential patterns are automatically redacted before submission,`,`but redaction is best-effort and is not a substitute for caution.`].join(`
59
- `),fe=p.object({description:p.string().min(10,`Provide enough context to reproduce (>=10 chars)`).max(8e3).describe(`Detailed description. NO secrets, customer data, or internal URLs.`),severity:p.enum([`low`,`medium`,`high`]).optional().describe(`Severity hint (optional)`),title:p.string().min(5,`Title must be at least 5 characters`).max(200).describe(`Brief, public-safe summary`),type:p.enum([`bug`,`feature`,`feedback`,`question`]).default(`feedback`).describe(`What kind of report this is`)}),pe=(e,t)=>{if(!e.redacted&&!t.redacted)return;let n=new Map;for(let r of[...e.matches,...t.matches])n.set(r.name,(n.get(r.name)??0)+r.count);return[`⚠️ Automatic redactions applied:`,...Array.from(n.entries()).map(([e,t])=>`- ${e}: ${String(t)}`)].join(`
60
- `)},me=e=>{if(!(!e||Object.keys(e).length===0))return[`---`,`**Context (auto-collected):**`,"```json",JSON.stringify(e,null,2),"```"].join(`
61
- `)},he=(e,t,n,r,i)=>{let a=[];return a.push(`**Type:** ${t}`),n&&a.push(`**Severity:** ${n}`),a.push(``),a.push(e),r&&(a.push(``),a.push(r)),i&&(a.push(``),a.push(i)),a.join(`
62
- `)},ge=e=>{let t=e.redactionPatterns??Q;return{annotations:{destructiveHint:!1,readOnlyHint:!1},description:e.description??de,execute:async n=>{let r=$(n.title,t),i=$(n.description,t),a=e.enrichment?await e.enrichment({severity:n.severity,type:n.type}):void 0,o=pe(r,i),s=me(a),c=he(i.text,n.type,n.severity,o,s),l=[n.type,...n.severity?[`severity:${n.severity}`]:[],...e.extraLabels??[]],u=await e.provider.submit({body:c,labels:l,title:r.text});return u.success?JSON.stringify({id:u.id,provider:e.provider.name,redacted:o!==void 0,redactionDetails:[...r.matches,...i.matches],success:!0,url:u.url},null,2):JSON.stringify({error:u.error,redacted:o!==void 0,success:!1},null,2)},name:e.name??`report_feedback`,parameters:fe}},_e=e=>{let t=e.baseUrl??`https://api.github.com`,n=e.fetchImpl??fetch;return{name:`github`,submit:async r=>{let i=e.getToken();if(!i)return{error:`No GitHub token configured`,success:!1};let a=[...e.defaultLabels??[],...r.labels],o=JSON.stringify({body:r.body,labels:Array.from(new Set(a)),title:r.title});try{let r=await n(`${t}/repos/${e.repo}/issues`,{body:o,headers:{Accept:`application/vnd.github+json`,Authorization:`Bearer ${i}`,"Content-Type":`application/json`,"X-GitHub-Api-Version":`2022-11-28`},method:`POST`}),a=await r.json().catch(()=>({}));return r.ok?{id:a.number===void 0?void 0:String(a.number),success:!0,url:a.html_url}:{error:`GitHub API ${String(r.status)}: ${a.message??r.statusText}`,success:!1}}catch(e){return{error:e instanceof Error?e.message:`Unknown error submitting to GitHub`,success:!1}}}}},ve=e=>{let t=e.fetchImpl??fetch,n=e.transform??(e=>e);return{name:`webhook`,submit:async r=>{try{let i=await t(e.url,{body:JSON.stringify(n(r)),headers:{"Content-Type":`application/json`,...e.headers??{}},method:`POST`});if(!i.ok){let e=await i.text().catch(()=>``);return{error:`Webhook ${String(i.status)}: ${e||i.statusText}`,success:!1}}return{success:!0}}catch(e){return{error:e instanceof Error?e.message:`Unknown error posting to webhook`,success:!1}}}}};export{x as DEFAULT_HEALTH_DETAIL_PATH,b as DEFAULT_HEALTH_PATH,w as DEFAULT_INFO_PATH,Q as DEFAULT_REDACTION_PATTERNS,z as NoopTelemetry,ne as UserError,oe as audioContent,F as classifyError,ce as createCapabilitiesTool,M as createCompositeTelemetry,le as createConnectionsTool,P as createConsoleTelemetry,_ as createDashboardArtifact,se as createDefaultLogger,L as createEnrichedError,E as createFastMCPBackend,ge as createFeedbackTool,A as createGateway,j as createGatewayManager,_e as createGithubFeedback,S as createHealthArtifact,C as createHealthDetailArtifact,ue as createHealthTool,T as createInfoArtifact,J as createInfoTool,R as createJsonFileTelemetry,N as createLogLayerTelemetry,q as createProxiedTools,Y as createServer,ve as createWebhookFeedback,te as getRuntimeInfo,ae as imageContent,O as readBuildInfoFromEnv,$ as redact,g as registerArtifacts,k as resolveBuildInfo,G as wrapPrompt,W as wrapResource,U as wrapTool};
57
+ </html>`,v=e=>{let t=Math.floor(e/1e3),n=Math.floor(t/60),r=Math.floor(n/60),i=Math.floor(r/24);return i>0?`${String(i)}d ${String(r%24)}h`:r>0?`${String(r)}h ${String(n%60)}m`:n>0?`${String(n)}m ${String(t%60)}s`:`${String(t)}s`},y=`/health`,b=`/health/detail`,ee=(e,t=y)=>({handler:()=>{let t=e(),n=t.status===`running`?200:503;return new Response(JSON.stringify({name:t.name,status:t.status}),{headers:{"Content-Type":`application/json`},status:n})},path:t,type:`dynamic`}),x=(e,t=b)=>({handler:()=>{let t=e(),n=t.status===`running`?200:503;return new Response(JSON.stringify(t),{headers:{"Content-Type":`application/json`},status:n})},path:t,protected:!0,type:`dynamic`}),S=`/info`,C=(e,t=S)=>({handler:()=>new Response(JSON.stringify(e()),{headers:{"Content-Type":`application/json`},status:200}),path:t,protected:!0,type:`dynamic`}),w=e=>{let t=process.env[e];return t&&t.length>0?t:void 0},T=()=>({branch:w(`SOMAMCP_BUILD_BRANCH`),commit:w(`SOMAMCP_BUILD_COMMIT`),date:w(`SOMAMCP_BUILD_DATE`),environment:w(`SOMAMCP_ENVIRONMENT`)}),te=e=>{let t=T();return{branch:e?.branch??t.branch,commit:e?.commit??t.commit,date:e?.date??t.date,environment:e?.environment??t.environment}},E=()=>({arch:process.arch,nodeVersion:process.version,platform:process.platform}),D=(e,o)=>{let s=n(t.none()),c=n(t.none()),l=n([]),u=n(`disconnected`),d=n(t.none()),f=e.name??e.id,p=()=>{let n=e.reconnectIntervalMs??5e3;d.set(t(setTimeout(()=>{m.connect()},n)))},m={get config(){return e},get info(){return{id:e.id,name:f,remoteTools:l.get().map(e=>({description:e.description,name:e.name})),status:u.get(),url:e.url}},get name(){return f},get status(){return u.get()},get tools(){return l.get()},async callTool(t,n={}){let r=s.get();if(r.isEmpty||u.get()!==`connected`)throw Error(`Gateway ${e.id} is not connected`);return r.orThrow(Error(`Gateway ${e.id} is not connected`)).callTool({arguments:n,name:t})},async connect(){if(u.get()===`connected`)return;u.set(`connecting`);let n=Date.now();(await r.fromPromise((async()=>{let n=new a(new URL(e.url));c.set(t(n));let r=new i({name:`soma-gateway-${e.id}`,version:`1.0.0`});s.set(t(r)),await r.connect(n);let o=await r.listTools();l.set(o.tools)})())).fold(t=>{u.set(`error`),o.recordEvent({data:{id:e.id,url:e.url},error:t instanceof Error?t.message:String(t),name:f,timestamp:n,type:`gateway.error`}),e.reconnect!==!1&&p()},()=>{u.set(`connected`),o.recordEvent({data:{id:e.id,remoteToolCount:l.get().length,url:e.url},durationMs:Date.now()-n,name:f,timestamp:n,type:`gateway.connect`})})},async disconnect(){d.get().match({None:()=>void 0,Some:e=>clearTimeout(e)}),d.set(t.none());let n=s.get();n.isSome()&&await r.fromPromise(n.value.close()),s.set(t.none()),c.set(t.none()),l.set([]),u.set(`disconnected`),o.recordEvent({data:{id:e.id},name:f,timestamp:Date.now(),type:`gateway.disconnect`})}};return m},O=e=>{let n=new Map;return{get connectedCount(){return[...n.values()].filter(e=>e.status===`connected`).length},get totalCount(){return n.size},add(t){let r=D(t,e);return n.set(t.id,r),r},async connectAll(){await Promise.allSettled([...n.values()].map(e=>e.connect()))},async disconnectAll(){await Promise.allSettled([...n.values()].map(e=>e.disconnect()))},get(e){return t(n.get(e))},getAll(){return[...n.values()]},getInfoAll(){return[...n.values()].map(e=>e.info)}}},k=e=>({flush:async()=>{await Promise.all(e.map(e=>e.flush?e.flush():Promise.resolve()))},recordEvent:t=>{e.forEach(e=>e.recordEvent(t))}}),A=e=>({flush:()=>Promise.resolve(),recordEvent:t=>{let n={durationMs:t.durationMs,eventName:t.name,timestamp:new Date(t.timestamp).toISOString(),type:t.type,...t.sessionId&&{sessionId:t.sessionId},...t.requestId&&{requestId:t.requestId},...t.errorCategory&&{errorCategory:t.errorCategory},...t.data};t.error?e.withError(Error(t.error)).error(t.type,n):e.info(t.type,n)}}),j=(e=`[soma]`)=>A(o({prefix:e,stream:`stderr`})),M=e=>{if(e instanceof Error){let t=e.message.toLowerCase();if(t.includes(`validation`)||t.includes(`invalid`)||t.includes(`schema`))return`validation`;if(t.includes(`timeout`)||t.includes(`timed out`)||t.includes(`etimedout`))return`timeout`;if(t.includes(`gateway`)||t.includes(`not connected`)||t.includes(`econnrefused`)||t.includes(`connection refused`))return`gateway`;if(t.includes(`auth`)||t.includes(`unauthorized`)||t.includes(`forbidden`))return`auth`;if(t.includes(`not found`)||t.includes(`404`))return`not_found`}return typeof e==`object`&&e&&`name`in e&&e.name===`UserError`?`validation`:`internal`},N=(e,t)=>{switch(e){case`validation`:return[`Check the tool's parameter schema and provide valid input`];case`timeout`:return[`The operation timed out. Try again or reduce the scope of the request`];case`gateway`:return[`Gateway is ${t?.gatewayStatus??`unavailable`}. The remote service may be down`,`Try again later or check the remote service status`];case`auth`:return[`Authentication failed. Check credentials or permissions`];case`not_found`:return[`The requested resource was not found. Verify the identifier`];case`internal`:return[`An internal error occurred. The tool maintainer should investigate`]}},P=(e,t)=>{let n=M(e),r=e instanceof Error?e.message:String(e),i=N(n,t),a={...t?.gatewayStatus&&{gatewayStatus:t.gatewayStatus},...t?.toolName&&{toolName:t.toolName}};return{errorCategory:n,message:r,...Object.keys(a).length>0&&{relatedState:a},suggestions:i}},F=e=>{let r=n([]),i=n(t.none()),a=n(!1),o=async()=>{let t=r.getAndSet([]);if(t.length===0)return;a.get()||(await c(u(e.filePath),{recursive:!0}),a.set(!0));let n=`${t.map(e=>JSON.stringify(e)).join(`
58
+ `)}\n`;await s(e.filePath,n)},l=()=>{i.get().isSome()||i.set(t(setTimeout(()=>{i.set(t.none()),o()},e.flushIntervalMs??1e3)))};return{flush:async()=>{i.get().match({None:()=>void 0,Some:e=>clearTimeout(e)}),i.set(t.none()),await o()},recordEvent:e=>{r.update(t=>[...t,e]),l()}}},I={flush:()=>Promise.resolve(),recordEvent:()=>{}},L=(e,t)=>!t||t.length===0?e:Object.fromEntries(Object.entries(e).map(([e,n])=>[e,t.includes(e)?`[REDACTED]`:n])),R=(e,t=1e4)=>{let n=typeof e==`string`?e:JSON.stringify(e);return n&&n.length>t?`${n.slice(0,t)}...[truncated, ${n.length} total chars]`:e},z=e=>r.fromPromise(e),B=(e,t,n)=>({...e,execute:async(r,i)=>{let a=n?.captureLevel??`full`;if(a===`none`)return e.execute(r,i);let o=Date.now(),{requestId:s,sessionId:c}=i,l=a===`full`?L(r,n?.redactInputFields):void 0;return(await z(e.execute(r,i))).fold(n=>{let r=P(n,{toolName:e.name});return t.recordEvent({data:{name:e.name},durationMs:Date.now()-o,error:r.message,errorCategory:r.errorCategory,errorStack:n.stack,input:l,name:e.name,requestId:s,sessionId:c,timestamp:o,type:`tool.error`}),{content:[{text:JSON.stringify(r,null,2),type:`text`}],isError:!0}},r=>(t.recordEvent({data:{name:e.name},durationMs:Date.now()-o,input:l,name:e.name,output:a===`full`?R(r,n?.maxOutputSize):void 0,requestId:s,sessionId:c,timestamp:o,type:`tool.execute`}),r))}}),V=(e,t)=>({...e,load:async n=>{let r=Date.now();return(await z(e.load(n))).fold(n=>{let i=P(n);throw t.recordEvent({data:{name:e.name,uri:e.uri},durationMs:Date.now()-r,error:i.message,errorCategory:i.errorCategory,errorStack:n.stack,name:e.name,timestamp:r,type:`resource.error`}),n},n=>(t.recordEvent({data:{name:e.name,uri:e.uri},durationMs:Date.now()-r,name:e.name,timestamp:r,type:`resource.load`}),n))}}),H=(e,t)=>({...e,load:async(n,r)=>{let i=Date.now();return(await z(e.load(n,r))).fold(n=>{let r=P(n);throw t.recordEvent({data:{name:e.name},durationMs:Date.now()-i,error:r.message,errorCategory:r.errorCategory,errorStack:n.stack,name:e.name,timestamp:i,type:`prompt.error`}),n},n=>(t.recordEvent({data:{name:e.name},durationMs:Date.now()-i,name:e.name,timestamp:i,type:`prompt.load`}),n))}}),U=e=>r.fromPromise(e),W=(e,t)=>{let n=e.config.toolPrefix??`${e.config.id}_`;return e.tools.map(r=>({annotations:{openWorldHint:!0,readOnlyHint:!0},description:`[${e.name}] ${r.description??`Remote tool`}`,execute:async i=>{let a=Date.now(),o=`${n}${r.name}`;return(await U(e.callTool(r.name,i))).fold(n=>{let s=P(n,{gatewayStatus:e.status,toolName:r.name});return t?.recordEvent({data:{gateway:e.config.id,remoteTool:r.name},durationMs:Date.now()-a,error:s.message,errorCategory:s.errorCategory,errorStack:n.stack,input:i,name:o,timestamp:a,type:`tool.error`}),{content:[{text:JSON.stringify(s,null,2),type:`text`}],isError:!0}},n=>(t?.recordEvent({data:{gateway:e.config.id,remoteTool:r.name},durationMs:Date.now()-a,input:i,name:o,output:n,timestamp:a,type:`tool.execute`}),JSON.stringify(n,null,2)))},name:`${n}${r.name}`}))},G=(e,t=`info`)=>({annotations:{readOnlyHint:!0},description:`Returns identity and build information for this server (name, version, build commit, runtime, capability counts)`,execute:()=>Promise.resolve(JSON.stringify(e(),null,2)),name:t}),K=t=>{let{artifacts:r,backendOptions:i,build:a,enableDashboard:o,enableHealthEndpoint:s,enableInfoEndpoint:c,enableIntrospection:l,gateways:u,healthDetailPath:d,healthPath:f,infoPath:p,introspectionPrefix:m,logLayer:_,telemetry:v,...y}=t,b=y.name,S=y.version,w=te(a),T=E(),D=m??``,k=v??(_?A(_):I),j=e(y,i),M=O(k),N=[],P=[],F=[],L=n(0);u?.forEach(e=>M.add(e));let R=()=>{let e=L.get(),t=e>0?Date.now()-e:0;return{activeSessions:j.sessions.length,gateways:{connected:M.connectedCount,total:M.totalCount},name:b,startedAt:e,status:j.serverState,uptime:t}},z=()=>({prompts:F,resources:P,tools:N}),U=()=>({build:w,capabilities:{prompts:F.length,resources:P.length,tools:N.length},name:b,runtime:T,version:S});l!==!1&&j.addTool(G(()=>U(),`${D}info`));let K=[...r??[]];s!==!1&&(K.push(ee(()=>R(),f)),K.push(x(()=>R(),d))),c!==!1&&K.push(C(()=>U(),p)),o!==!1&&K.push(g(()=>R(),()=>z(),()=>M.getInfoAll())),K.length>0&&h(j.getApp(),K,y.authenticate),j.on(`connect`,({session:e})=>{k.recordEvent({data:{sessionId:e.sessionId},name:b,timestamp:Date.now(),type:`session.connect`})}),j.on(`disconnect`,({session:e})=>{k.recordEvent({data:{sessionId:e.sessionId},name:b,timestamp:Date.now(),type:`session.disconnect`})});let q=e=>{let t=B(e,k,`captureConfig`in e?e.captureConfig:void 0);j.addTool(t),N.push({description:e.description,name:e.name})},J=e=>{let t=V(e,k);j.addResource(t),P.push({description:e.description,name:e.name,uri:e.uri})},Y=e=>{let t=H(e,k);j.addPrompt(t),F.push({description:e.description,name:e.name})};return{get name(){return b},get serverState(){return j.serverState},get sessions(){return j.sessions},addPrompt:Y,addPrompts:e=>{e.forEach(Y)},addResource:J,addResources:e=>{e.forEach(J)},addResourceTemplate:(...e)=>{j.addResourceTemplate(...e)},addTool:q,addTools:e=>{e.forEach(e=>q(e))},getApp:()=>j.getApp(),getCapabilities:z,getGatewayManager:()=>M,getHealth:R,getInfo:U,removePrompt:e=>{j.removePrompt(e)},removeResource:e=>{j.removeResource(e)},removeTool:e=>{j.removeTool(e)},async start(e){L.set(Date.now()),k.recordEvent({name:b,timestamp:L.get(),type:`server.start`}),await j.start(e),await M.connectAll(),M.getAll().filter(e=>e.status===`connected`&&e.config.proxyTools!==!1).forEach(e=>{W(e,k).forEach(e=>j.addTool(e))})},async stop(){await M.disconnectAll(),await j.stop(),k.recordEvent({name:b,timestamp:Date.now(),type:`server.stop`}),k.flush&&await k.flush()}}};var q=class extends Error{constructor(e){super(e),this.name=`UserError`}};const J={".avif":`image/avif`,".bmp":`image/bmp`,".gif":`image/gif`,".ico":`image/x-icon`,".jpeg":`image/jpeg`,".jpg":`image/jpeg`,".png":`image/png`,".svg":`image/svg+xml`,".tiff":`image/tiff`,".webp":`image/webp`},Y={".aac":`audio/aac`,".flac":`audio/flac`,".m4a":`audio/mp4`,".mp3":`audio/mpeg`,".ogg":`audio/ogg`,".opus":`audio/opus`,".wav":`audio/wav`,".weba":`audio/webm`},X=(e,t,n)=>t[d(new URL(e,`file:///`).pathname).toLowerCase()]??n,Z=async(e,t)=>{if(`url`in e){let n=await fetch(e.url);if(!n.ok)throw Error(`Failed to fetch ${t} from URL (${e.url}): ${n.status} ${n.statusText}`);return{data:Buffer.from(await n.arrayBuffer()),source:e.url}}return`path`in e?{data:await l(e.path),source:e.path}:{data:e.buffer}},ne=async e=>{let{data:t,source:n}=await Z(e,`image`),r=n?X(n,J,`image/png`):`image/png`;return{data:t.toString(`base64`),mimeType:r,type:`image`}},re=async e=>{let{data:t,source:n}=await Z(e,`audio`),r=n?X(n,Y,`audio/mpeg`):`audio/mpeg`;return{data:t.toString(`base64`),mimeType:r,type:`audio`}},ie=e=>o({prefix:`[${e}]`,stream:`stderr`}).withContext({cell:e}),ae=e=>({annotations:{readOnlyHint:!0},description:`Lists all tools, resources, and prompts registered on this server`,execute:()=>Promise.resolve(JSON.stringify(e(),null,2)),name:`soma_capabilities`}),oe=e=>({annotations:{readOnlyHint:!0},description:`Lists all gateway connections to remote servers with their status and available tools`,execute:()=>Promise.resolve(JSON.stringify(e(),null,2)),name:`soma_connections`}),se=e=>({annotations:{readOnlyHint:!0},description:`Returns health and status information for this server including uptime, sessions, and gateway status`,execute:()=>Promise.resolve(JSON.stringify(e(),null,2)),name:`soma_health`}),Q=[{description:`GitHub personal access token`,name:`github_pat`,pattern:/\b(?:ghp|gho|ghu|ghs|ghr|github_pat)_[A-Za-z0-9_]{20,}\b/g},{description:`AWS access key ID`,name:`aws_access_key`,pattern:/\bAKIA[0-9A-Z]{16}\b/g},{description:`AWS secret access key (heuristic)`,name:`aws_secret_key`,pattern:/(?<![A-Za-z0-9/+])[A-Za-z0-9/+]{40}(?![A-Za-z0-9/+])/g},{description:`Stripe secret/publishable key`,name:`stripe_key`,pattern:/\b(?:sk|pk|rk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g},{description:`Slack token`,name:`slack_token`,pattern:/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g},{description:`JSON Web Token`,name:`jwt`,pattern:/\beyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]+\b/g},{description:`OpenAI / Anthropic style API key`,name:`ai_api_key`,pattern:/\b(?:sk-ant-|sk-)[A-Za-z0-9_-]{20,}\b/g},{description:`Generic bearer-style secret prefix`,name:`bearer_authorization`,pattern:/\b[Bb]earer\s+[A-Za-z0-9._\-+/]{16,}\b/g},{description:`Email address`,name:`email`,pattern:/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g},{description:`Private IPv4 address (RFC1918)`,name:`private_ipv4`,pattern:/\b(?:10(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2})\b/g},{description:`URL pointing at internal/private hostname`,name:`internal_url`,pattern:/\bhttps?:\/\/(?:[a-z0-9-]+\.)*(?:internal|intranet|corp|local|lan)(?:[/:][^\s]*)?/gi}],$=(e,t=Q)=>{let{counts:n,text:r}=t.reduce((e,t)=>{let n=Array.from(e.text.matchAll(t.pattern)).length;return n===0?e:{counts:new Map(e.counts).set(t.name,n),text:e.text.replace(t.pattern,t.replacement??`[REDACTED]`)}},{counts:new Map,text:e}),i=Array.from(n.entries()).map(([e,t])=>({count:t,name:e}));return{matches:i,redacted:i.length>0,text:r}},ce=[`Submit a feedback report or issue to this server's maintainers.`,``,`IMPORTANT: Treat all input as potentially public.`,`- Do NOT include API keys, tokens, passwords, or credentials`,`- Do NOT include customer data, PII, or proprietary information`,`- Do NOT include internal URLs, hostnames, or system topology`,`- Describe the behavior and how to reproduce it, not the data involved`,``,`Common credential patterns are automatically redacted before submission,`,`but redaction is best-effort and is not a substitute for caution.`].join(`
59
+ `),le=f.object({description:f.string().min(10,`Provide enough context to reproduce (>=10 chars)`).max(8e3).describe(`Detailed description. NO secrets, customer data, or internal URLs.`),severity:f.enum([`low`,`medium`,`high`]).optional().describe(`Severity hint (optional)`),title:f.string().min(5,`Title must be at least 5 characters`).max(200).describe(`Brief, public-safe summary`),type:f.enum([`bug`,`feature`,`feedback`,`question`]).default(`feedback`).describe(`What kind of report this is`)}),ue=(e,t)=>{if(!e.redacted&&!t.redacted)return;let n=new Map;for(let r of[...e.matches,...t.matches])n.set(r.name,(n.get(r.name)??0)+r.count);return[`⚠️ Automatic redactions applied:`,...Array.from(n.entries()).map(([e,t])=>`- ${e}: ${String(t)}`)].join(`
60
+ `)},de=e=>{if(!(!e||Object.keys(e).length===0))return[`---`,`**Context (auto-collected):**`,"```json",JSON.stringify(e,null,2),"```"].join(`
61
+ `)},fe=(e,t,n,r,i)=>{let a=[];return a.push(`**Type:** ${t}`),n&&a.push(`**Severity:** ${n}`),a.push(``),a.push(e),r&&(a.push(``),a.push(r)),i&&(a.push(``),a.push(i)),a.join(`
62
+ `)},pe=e=>{let t=e.redactionPatterns??Q;return{annotations:{destructiveHint:!1,readOnlyHint:!1},description:e.description??ce,execute:async n=>{let r=$(n.title,t),i=$(n.description,t),a=e.enrichment?await e.enrichment({severity:n.severity,type:n.type}):void 0,o=ue(r,i),s=de(a),c=fe(i.text,n.type,n.severity,o,s),l=[n.type,...n.severity?[`severity:${n.severity}`]:[],...e.extraLabels??[]],u=await e.provider.submit({body:c,labels:l,title:r.text});return u.success?JSON.stringify({id:u.id,provider:e.provider.name,redacted:o!==void 0,redactionDetails:[...r.matches,...i.matches],success:!0,url:u.url},null,2):JSON.stringify({error:u.error,redacted:o!==void 0,success:!1},null,2)},name:e.name??`report_feedback`,parameters:le}},me=e=>{let t=e.baseUrl??`https://api.github.com`,n=e.fetchImpl??fetch;return{name:`github`,submit:async r=>{let i=e.getToken();if(!i)return{error:`No GitHub token configured`,success:!1};let a=[...e.defaultLabels??[],...r.labels],o=JSON.stringify({body:r.body,labels:Array.from(new Set(a)),title:r.title});try{let r=await n(`${t}/repos/${e.repo}/issues`,{body:o,headers:{Accept:`application/vnd.github+json`,Authorization:`Bearer ${i}`,"Content-Type":`application/json`,"X-GitHub-Api-Version":`2022-11-28`},method:`POST`}),a=await r.json().catch(()=>({}));return r.ok?{id:a.number===void 0?void 0:String(a.number),success:!0,url:a.html_url}:{error:`GitHub API ${String(r.status)}: ${a.message??r.statusText}`,success:!1}}catch(e){return{error:e instanceof Error?e.message:`Unknown error submitting to GitHub`,success:!1}}}}},he=e=>{let t=e.fetchImpl??fetch,n=e.transform??(e=>e);return{name:`webhook`,submit:async r=>{try{let i=await t(e.url,{body:JSON.stringify(n(r)),headers:{"Content-Type":`application/json`,...e.headers??{}},method:`POST`});if(!i.ok){let e=await i.text().catch(()=>``);return{error:`Webhook ${String(i.status)}: ${e||i.statusText}`,success:!1}}return{success:!0}}catch(e){return{error:e instanceof Error?e.message:`Unknown error posting to webhook`,success:!1}}}}};export{b as DEFAULT_HEALTH_DETAIL_PATH,y as DEFAULT_HEALTH_PATH,S as DEFAULT_INFO_PATH,Q as DEFAULT_REDACTION_PATTERNS,I as NoopTelemetry,q as UserError,re as audioContent,M as classifyError,ae as createCapabilitiesTool,k as createCompositeTelemetry,oe as createConnectionsTool,j as createConsoleTelemetry,g as createDashboardArtifact,ie as createDefaultLogger,P as createEnrichedError,e as createFastMCPBackend,pe as createFeedbackTool,D as createGateway,O as createGatewayManager,me as createGithubFeedback,ee as createHealthArtifact,x as createHealthDetailArtifact,se as createHealthTool,C as createInfoArtifact,G as createInfoTool,F as createJsonFileTelemetry,A as createLogLayerTelemetry,W as createProxiedTools,K as createServer,he as createWebhookFeedback,E as getRuntimeInfo,ne as imageContent,T as readBuildInfoFromEnv,$ as redact,h as registerArtifacts,te as resolveBuildInfo,H as wrapPrompt,V as wrapResource,B as wrapTool};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "somamcp",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Framework for building MCP servers with telemetry, introspection, and backend abstraction",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -64,8 +64,8 @@
64
64
  "devDependencies": {
65
65
  "@types/node": "^24.12.4",
66
66
  "get-port-please": "^3.2.0",
67
- "ts-builds": "^2.8.1",
67
+ "ts-builds": "^3.0.0",
68
68
  "tsdown": "^0.22.1"
69
69
  },
70
- "packageManager": "pnpm@10.33.3+sha512.a19744364a7e248b92657a4ca5973f9354d21caf982579674b1c539f32c7420c47138ad8b1254df07aba9bc782d9b3029e3db34d5dbff974326eb74dac8ff489"
70
+ "packageManager": "pnpm@11.5.1+sha512.93f7b57422ea7068257235b4c16eb60762eb68e1dc23723199cc739043ea9be2c4143274a399d8c6defa2b1176226d9ca1c4b63482d6200c1a8fbaa78c1d1485"
71
71
  }