somamcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +444 -0
- package/dist/index.js +58 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Jordan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { DirectLogger, DirectLogger as DirectLogger$1 } from "functype-log";
|
|
2
|
+
import { Context as Context$1, Hono } from "hono";
|
|
3
|
+
import { Tool as Tool$1 } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
+
|
|
5
|
+
//#region src/artifacts/types.d.ts
|
|
6
|
+
type StaticArtifact = {
|
|
7
|
+
contentType: string;
|
|
8
|
+
content: string;
|
|
9
|
+
path: string;
|
|
10
|
+
type: "static";
|
|
11
|
+
};
|
|
12
|
+
type DynamicArtifact = {
|
|
13
|
+
handler: (c: Context$1) => Response | Promise<Response>;
|
|
14
|
+
path: string;
|
|
15
|
+
type: "dynamic";
|
|
16
|
+
};
|
|
17
|
+
type DirectoryArtifact = {
|
|
18
|
+
directory: string;
|
|
19
|
+
path: string;
|
|
20
|
+
type: "directory";
|
|
21
|
+
};
|
|
22
|
+
type ArtifactConfig = DirectoryArtifact | DynamicArtifact | StaticArtifact;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/types/core.d.ts
|
|
25
|
+
type SessionAuth = Record<string, unknown> | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Structural type compatible with StandardSchemaV1 (zod, valibot, etc.)
|
|
28
|
+
* We define this structurally to avoid a direct dependency on @standard-schema/spec.
|
|
29
|
+
*/
|
|
30
|
+
type SchemaParams = {
|
|
31
|
+
readonly "~standard": {
|
|
32
|
+
readonly version: 1;
|
|
33
|
+
readonly vendor: string;
|
|
34
|
+
readonly types?: {
|
|
35
|
+
readonly input: unknown;
|
|
36
|
+
readonly output: unknown;
|
|
37
|
+
} | undefined;
|
|
38
|
+
readonly validate: (value: unknown) => {
|
|
39
|
+
value: unknown;
|
|
40
|
+
} | {
|
|
41
|
+
issues: ReadonlyArray<{
|
|
42
|
+
message: string;
|
|
43
|
+
}>;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
type InferSchemaOutput<P extends SchemaParams> = NonNullable<P["~standard"]["types"]>["output"] extends infer O ? [O] extends [never] ? unknown : O : unknown;
|
|
48
|
+
type TextContent = {
|
|
49
|
+
text: string;
|
|
50
|
+
type: "text";
|
|
51
|
+
};
|
|
52
|
+
type ImageContent = {
|
|
53
|
+
data: string;
|
|
54
|
+
mimeType: string;
|
|
55
|
+
type: "image";
|
|
56
|
+
};
|
|
57
|
+
type AudioContent = {
|
|
58
|
+
data: string;
|
|
59
|
+
mimeType: string;
|
|
60
|
+
type: "audio";
|
|
61
|
+
};
|
|
62
|
+
type ResourceContent = {
|
|
63
|
+
resource: {
|
|
64
|
+
blob?: string;
|
|
65
|
+
mimeType?: string;
|
|
66
|
+
text?: string;
|
|
67
|
+
uri: string;
|
|
68
|
+
};
|
|
69
|
+
type: "resource";
|
|
70
|
+
};
|
|
71
|
+
type ResourceLink = {
|
|
72
|
+
mimeType?: string;
|
|
73
|
+
name?: string;
|
|
74
|
+
type: "resource_link";
|
|
75
|
+
uri: string;
|
|
76
|
+
};
|
|
77
|
+
type Content = AudioContent | ImageContent | ResourceContent | ResourceLink | TextContent;
|
|
78
|
+
type ContentResult = {
|
|
79
|
+
content: Content[];
|
|
80
|
+
isError?: boolean;
|
|
81
|
+
};
|
|
82
|
+
type Progress = {
|
|
83
|
+
progress: number;
|
|
84
|
+
total?: number;
|
|
85
|
+
};
|
|
86
|
+
type Context<T extends SessionAuth = SessionAuth> = {
|
|
87
|
+
client: {
|
|
88
|
+
version: unknown;
|
|
89
|
+
};
|
|
90
|
+
log: {
|
|
91
|
+
debug: (message: string, data?: unknown) => void;
|
|
92
|
+
error: (message: string, data?: unknown) => void;
|
|
93
|
+
info: (message: string, data?: unknown) => void;
|
|
94
|
+
warn: (message: string, data?: unknown) => void;
|
|
95
|
+
};
|
|
96
|
+
reportProgress: (progress: Progress) => Promise<void>;
|
|
97
|
+
requestId?: string;
|
|
98
|
+
session: T | undefined;
|
|
99
|
+
sessionId?: string;
|
|
100
|
+
streamContent: (content: Content | Content[]) => Promise<void>;
|
|
101
|
+
};
|
|
102
|
+
type ToolAnnotations = {
|
|
103
|
+
destructiveHint?: boolean;
|
|
104
|
+
idempotentHint?: boolean;
|
|
105
|
+
openWorldHint?: boolean;
|
|
106
|
+
readOnlyHint?: boolean;
|
|
107
|
+
streamingHint?: boolean;
|
|
108
|
+
title?: string;
|
|
109
|
+
};
|
|
110
|
+
type Tool<T extends SessionAuth = SessionAuth, P extends SchemaParams = SchemaParams> = {
|
|
111
|
+
_meta?: {
|
|
112
|
+
[key: string]: unknown;
|
|
113
|
+
ui?: {
|
|
114
|
+
resourceUri?: string;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
annotations?: ToolAnnotations;
|
|
118
|
+
canAccess?: (auth: T) => boolean;
|
|
119
|
+
description?: string;
|
|
120
|
+
execute: (args: InferSchemaOutput<P>, context: Context<T>) => Promise<Content | ContentResult | string | void>;
|
|
121
|
+
name: string;
|
|
122
|
+
outputSchema?: SchemaParams;
|
|
123
|
+
parameters?: P;
|
|
124
|
+
timeoutMs?: number;
|
|
125
|
+
};
|
|
126
|
+
type Completion = {
|
|
127
|
+
hasMore?: boolean;
|
|
128
|
+
total?: number;
|
|
129
|
+
values: string[];
|
|
130
|
+
};
|
|
131
|
+
type ResourceResult = {
|
|
132
|
+
blob: string;
|
|
133
|
+
mimeType?: string;
|
|
134
|
+
uri?: string;
|
|
135
|
+
} | {
|
|
136
|
+
mimeType?: string;
|
|
137
|
+
text: string;
|
|
138
|
+
uri?: string;
|
|
139
|
+
};
|
|
140
|
+
type Resource<T extends SessionAuth = SessionAuth> = {
|
|
141
|
+
complete?: (name: string, value: string, auth?: T) => Promise<Completion>;
|
|
142
|
+
description?: string;
|
|
143
|
+
load: (auth?: T) => Promise<ResourceResult | ResourceResult[]>;
|
|
144
|
+
mimeType?: string;
|
|
145
|
+
name: string;
|
|
146
|
+
uri: string;
|
|
147
|
+
};
|
|
148
|
+
type PromptArgument<T extends SessionAuth = SessionAuth> = Readonly<{
|
|
149
|
+
complete?: (value: string, auth?: T) => Promise<Completion>;
|
|
150
|
+
description?: string;
|
|
151
|
+
enum?: string[];
|
|
152
|
+
name: string;
|
|
153
|
+
required?: boolean;
|
|
154
|
+
}>;
|
|
155
|
+
type PromptResult = {
|
|
156
|
+
messages: unknown[];
|
|
157
|
+
} | string;
|
|
158
|
+
type Prompt<T extends SessionAuth = SessionAuth, Args extends PromptArgument<T>[] = PromptArgument<T>[]> = {
|
|
159
|
+
arguments?: Args;
|
|
160
|
+
complete?: (name: string, value: string, auth?: T) => Promise<Completion>;
|
|
161
|
+
description?: string;
|
|
162
|
+
load: (args: Record<string, string | undefined>, auth?: T) => Promise<PromptResult>;
|
|
163
|
+
name: string;
|
|
164
|
+
};
|
|
165
|
+
type ServerStatus = "error" | "running" | "stopped";
|
|
166
|
+
declare class UserError extends Error {
|
|
167
|
+
constructor(message: string);
|
|
168
|
+
}
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/types/server.d.ts
|
|
171
|
+
type Logger = {
|
|
172
|
+
debug: (...args: unknown[]) => void;
|
|
173
|
+
error: (...args: unknown[]) => void;
|
|
174
|
+
info: (...args: unknown[]) => void;
|
|
175
|
+
log: (...args: unknown[]) => void;
|
|
176
|
+
warn: (...args: unknown[]) => void;
|
|
177
|
+
};
|
|
178
|
+
type ServerConfig<T extends SessionAuth = SessionAuth> = {
|
|
179
|
+
authenticate?: (request: unknown) => Promise<T>;
|
|
180
|
+
instructions?: string;
|
|
181
|
+
logger?: Logger;
|
|
182
|
+
name: string;
|
|
183
|
+
version: `${number}.${number}.${number}`;
|
|
184
|
+
};
|
|
185
|
+
type TransportConfig = {
|
|
186
|
+
transportType: "stdio";
|
|
187
|
+
} | {
|
|
188
|
+
httpStream: {
|
|
189
|
+
enableJsonResponse?: boolean;
|
|
190
|
+
endpoint?: `/${string}`;
|
|
191
|
+
host?: string;
|
|
192
|
+
port: number;
|
|
193
|
+
};
|
|
194
|
+
transportType: "httpStream";
|
|
195
|
+
};
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/backend/adapter.d.ts
|
|
198
|
+
type BackendSession<T extends SessionAuth = SessionAuth> = {
|
|
199
|
+
sessionId?: string;
|
|
200
|
+
auth?: T;
|
|
201
|
+
};
|
|
202
|
+
type BackendEvents<T extends SessionAuth> = {
|
|
203
|
+
connect: (event: {
|
|
204
|
+
session: BackendSession<T>;
|
|
205
|
+
}) => void;
|
|
206
|
+
disconnect: (event: {
|
|
207
|
+
session: BackendSession<T>;
|
|
208
|
+
}) => void;
|
|
209
|
+
};
|
|
210
|
+
type BackendAdapter<T extends SessionAuth = SessionAuth> = {
|
|
211
|
+
readonly serverState: ServerStatus;
|
|
212
|
+
readonly sessions: ReadonlyArray<BackendSession<T>>;
|
|
213
|
+
addPrompt: <Args extends PromptArgument<T>[]>(prompt: Prompt<T, Args>) => void;
|
|
214
|
+
addResource: (resource: Resource<T>) => void;
|
|
215
|
+
addResourceTemplate: (...args: ReadonlyArray<unknown>) => void;
|
|
216
|
+
addTool: <P extends SchemaParams>(tool: Tool<T, P>) => void;
|
|
217
|
+
getApp: () => Hono;
|
|
218
|
+
on: <E extends keyof BackendEvents<T>>(event: E, handler: BackendEvents<T>[E]) => void;
|
|
219
|
+
removePrompt: (name: string) => void;
|
|
220
|
+
removeResource: (name: string) => void;
|
|
221
|
+
removeTool: (name: string) => void;
|
|
222
|
+
start: (transport?: TransportConfig) => Promise<void>;
|
|
223
|
+
stop: () => Promise<void>;
|
|
224
|
+
};
|
|
225
|
+
type BackendFactory<T extends SessionAuth = SessionAuth> = (config: {
|
|
226
|
+
authenticate?: (request: unknown) => Promise<T>;
|
|
227
|
+
instructions?: string;
|
|
228
|
+
name: string;
|
|
229
|
+
version: `${number}.${number}.${number}`;
|
|
230
|
+
}, backendOptions?: Record<string, unknown>) => BackendAdapter<T>;
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/gateway/types.d.ts
|
|
233
|
+
type GatewayConfig = {
|
|
234
|
+
id: string;
|
|
235
|
+
name?: string;
|
|
236
|
+
proxyTools?: boolean;
|
|
237
|
+
reconnect?: boolean;
|
|
238
|
+
reconnectIntervalMs?: number;
|
|
239
|
+
toolPrefix?: string;
|
|
240
|
+
url: string;
|
|
241
|
+
};
|
|
242
|
+
type GatewayStatus = "connected" | "connecting" | "disconnected" | "error";
|
|
243
|
+
type GatewayInfo = {
|
|
244
|
+
id: string;
|
|
245
|
+
name: string;
|
|
246
|
+
remoteTools: ReadonlyArray<{
|
|
247
|
+
description?: string;
|
|
248
|
+
name: string;
|
|
249
|
+
}>;
|
|
250
|
+
status: GatewayStatus;
|
|
251
|
+
url: string;
|
|
252
|
+
};
|
|
253
|
+
type GatewayInstance = {
|
|
254
|
+
readonly config: GatewayConfig;
|
|
255
|
+
readonly info: GatewayInfo;
|
|
256
|
+
readonly name: string;
|
|
257
|
+
readonly status: GatewayStatus;
|
|
258
|
+
readonly tools: ReadonlyArray<Tool$1>;
|
|
259
|
+
callTool: (name: string, args?: Record<string, unknown>) => Promise<unknown>;
|
|
260
|
+
connect: () => Promise<void>;
|
|
261
|
+
disconnect: () => Promise<void>;
|
|
262
|
+
};
|
|
263
|
+
type GatewayManagerInstance = {
|
|
264
|
+
readonly connectedCount: number;
|
|
265
|
+
readonly totalCount: number;
|
|
266
|
+
add: (config: GatewayConfig) => GatewayInstance;
|
|
267
|
+
connectAll: () => Promise<void>;
|
|
268
|
+
disconnectAll: () => Promise<void>;
|
|
269
|
+
get: (id: string) => GatewayInstance | undefined;
|
|
270
|
+
getAll: () => ReadonlyArray<GatewayInstance>;
|
|
271
|
+
getInfoAll: () => ReadonlyArray<GatewayInfo>;
|
|
272
|
+
};
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/telemetry/TelemetryCollector.d.ts
|
|
275
|
+
type TelemetryEventType = "server.start" | "server.stop" | "tool.execute" | "tool.error" | "resource.load" | "resource.error" | "prompt.load" | "prompt.error" | "gateway.connect" | "gateway.disconnect" | "gateway.error" | "session.connect" | "session.disconnect";
|
|
276
|
+
type ErrorCategory = "validation" | "timeout" | "gateway" | "internal" | "auth" | "not_found";
|
|
277
|
+
type CaptureLevel = "full" | "metadata" | "none";
|
|
278
|
+
type ToolCaptureConfig = {
|
|
279
|
+
captureLevel?: CaptureLevel;
|
|
280
|
+
maxOutputSize?: number;
|
|
281
|
+
redactInputFields?: ReadonlyArray<string>;
|
|
282
|
+
};
|
|
283
|
+
type TelemetryEvent = {
|
|
284
|
+
data?: Record<string, unknown>;
|
|
285
|
+
durationMs?: number;
|
|
286
|
+
error?: string;
|
|
287
|
+
errorCategory?: ErrorCategory;
|
|
288
|
+
errorStack?: string;
|
|
289
|
+
input?: Record<string, unknown>;
|
|
290
|
+
name: string;
|
|
291
|
+
output?: unknown;
|
|
292
|
+
requestId?: string;
|
|
293
|
+
sessionId?: string;
|
|
294
|
+
timestamp: number;
|
|
295
|
+
type: TelemetryEventType;
|
|
296
|
+
};
|
|
297
|
+
type TelemetryCollector = {
|
|
298
|
+
flush?: () => Promise<void>;
|
|
299
|
+
recordEvent: (event: TelemetryEvent) => void;
|
|
300
|
+
};
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region src/types.d.ts
|
|
303
|
+
type SomaServerOptions<T extends SessionAuth = SessionAuth> = ServerConfig<T> & {
|
|
304
|
+
artifacts?: ArtifactConfig[];
|
|
305
|
+
backendOptions?: Record<string, unknown>;
|
|
306
|
+
enableDashboard?: boolean;
|
|
307
|
+
enableIntrospection?: boolean;
|
|
308
|
+
gateways?: GatewayConfig[];
|
|
309
|
+
logLayer?: DirectLogger$1;
|
|
310
|
+
telemetry?: TelemetryCollector;
|
|
311
|
+
};
|
|
312
|
+
type ServerHealth = {
|
|
313
|
+
activeSessions: number;
|
|
314
|
+
gateways: {
|
|
315
|
+
connected: number;
|
|
316
|
+
total: number;
|
|
317
|
+
};
|
|
318
|
+
name: string;
|
|
319
|
+
startedAt: number;
|
|
320
|
+
status: ServerStatus;
|
|
321
|
+
uptime: number;
|
|
322
|
+
};
|
|
323
|
+
type ServerCapabilities = {
|
|
324
|
+
prompts: ReadonlyArray<{
|
|
325
|
+
description?: string;
|
|
326
|
+
name: string;
|
|
327
|
+
}>;
|
|
328
|
+
resources: ReadonlyArray<{
|
|
329
|
+
description?: string;
|
|
330
|
+
name: string;
|
|
331
|
+
uri: string;
|
|
332
|
+
}>;
|
|
333
|
+
tools: ReadonlyArray<{
|
|
334
|
+
description?: string;
|
|
335
|
+
name: string;
|
|
336
|
+
}>;
|
|
337
|
+
};
|
|
338
|
+
type ToolOptions<T extends SessionAuth = SessionAuth, P extends SchemaParams = SchemaParams> = Tool<T, P> & {
|
|
339
|
+
captureConfig?: ToolCaptureConfig;
|
|
340
|
+
};
|
|
341
|
+
type SomaServerInstance<T extends SessionAuth = SessionAuth> = {
|
|
342
|
+
readonly name: string;
|
|
343
|
+
readonly serverState: ServerStatus;
|
|
344
|
+
readonly sessions: ReadonlyArray<BackendSession<T>>;
|
|
345
|
+
addPrompt: <Args extends PromptArgument<T>[]>(prompt: Prompt<T, Args>) => void;
|
|
346
|
+
addPrompts: <Args extends PromptArgument<T>[]>(prompts: Prompt<T, Args>[]) => void;
|
|
347
|
+
addResource: (resource: Resource<T>) => void;
|
|
348
|
+
addResources: (resources: Resource<T>[]) => void;
|
|
349
|
+
addResourceTemplate: (...args: ReadonlyArray<unknown>) => void;
|
|
350
|
+
addTool: <P extends SchemaParams>(tool: Tool<T, P>) => void;
|
|
351
|
+
addTools: <P extends SchemaParams>(tools: Tool<T, P>[]) => void;
|
|
352
|
+
getApp: () => Hono;
|
|
353
|
+
getCapabilities: () => ServerCapabilities;
|
|
354
|
+
getGatewayManager: () => GatewayManagerInstance;
|
|
355
|
+
getHealth: () => ServerHealth;
|
|
356
|
+
removePrompt: (name: string) => void;
|
|
357
|
+
removeResource: (name: string) => void;
|
|
358
|
+
removeTool: (name: string) => void;
|
|
359
|
+
start: (options?: TransportConfig) => Promise<void>;
|
|
360
|
+
stop: () => Promise<void>;
|
|
361
|
+
};
|
|
362
|
+
//#endregion
|
|
363
|
+
//#region src/Server.d.ts
|
|
364
|
+
declare const createServer: <T extends SessionAuth = SessionAuth>(options: SomaServerOptions<T>) => SomaServerInstance<T>;
|
|
365
|
+
//#endregion
|
|
366
|
+
//#region src/content/helpers.d.ts
|
|
367
|
+
type ContentInput = {
|
|
368
|
+
buffer: Buffer;
|
|
369
|
+
} | {
|
|
370
|
+
path: string;
|
|
371
|
+
} | {
|
|
372
|
+
url: string;
|
|
373
|
+
};
|
|
374
|
+
declare const imageContent: (input: ContentInput) => Promise<ImageContent>;
|
|
375
|
+
declare const audioContent: (input: ContentInput) => Promise<AudioContent>;
|
|
376
|
+
//#endregion
|
|
377
|
+
//#region src/backend/fastmcp.d.ts
|
|
378
|
+
declare const createFastMCPBackend: <T extends SessionAuth = SessionAuth>(config: ServerConfig<T>, backendOptions?: Record<string, unknown>) => BackendAdapter<T>;
|
|
379
|
+
//#endregion
|
|
380
|
+
//#region src/telemetry/CompositeTelemetry.d.ts
|
|
381
|
+
declare const createCompositeTelemetry: (collectors: ReadonlyArray<TelemetryCollector>) => TelemetryCollector;
|
|
382
|
+
//#endregion
|
|
383
|
+
//#region src/telemetry/ConsoleTelemetry.d.ts
|
|
384
|
+
declare const createConsoleTelemetry: (prefix?: string) => TelemetryCollector;
|
|
385
|
+
//#endregion
|
|
386
|
+
//#region src/telemetry/EnrichedError.d.ts
|
|
387
|
+
type EnrichedErrorResponse = {
|
|
388
|
+
errorCategory: ErrorCategory;
|
|
389
|
+
message: string;
|
|
390
|
+
relatedState?: Record<string, unknown>;
|
|
391
|
+
suggestions?: ReadonlyArray<string>;
|
|
392
|
+
};
|
|
393
|
+
declare const classifyError: (error: unknown) => ErrorCategory;
|
|
394
|
+
declare const createEnrichedError: (error: unknown, context?: {
|
|
395
|
+
gatewayStatus?: string;
|
|
396
|
+
toolName?: string;
|
|
397
|
+
}) => EnrichedErrorResponse;
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/telemetry/JsonFileTelemetry.d.ts
|
|
400
|
+
type JsonFileTelemetryOptions = {
|
|
401
|
+
filePath: string;
|
|
402
|
+
flushIntervalMs?: number;
|
|
403
|
+
};
|
|
404
|
+
declare const createJsonFileTelemetry: (options: JsonFileTelemetryOptions) => TelemetryCollector;
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/telemetry/LogLayerTelemetry.d.ts
|
|
407
|
+
declare const createLogLayerTelemetry: (logger: DirectLogger$1) => TelemetryCollector;
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region src/telemetry/NoopTelemetry.d.ts
|
|
410
|
+
declare const NoopTelemetry: TelemetryCollector;
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region src/telemetry/telemetryWrapper.d.ts
|
|
413
|
+
declare const wrapTool: <T extends SessionAuth, P extends SchemaParams>(tool: Tool<T, P>, telemetry: TelemetryCollector, captureConfig?: ToolCaptureConfig) => Tool<T, P>;
|
|
414
|
+
declare const wrapResource: <T extends SessionAuth>(resource: Resource<T>, telemetry: TelemetryCollector) => Resource<T>;
|
|
415
|
+
declare const wrapPrompt: <T extends SessionAuth, Args extends PromptArgument<T>[] = PromptArgument<T>[]>(prompt: Prompt<T, Args>, telemetry: TelemetryCollector) => Prompt<T, Args>;
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region src/logging.d.ts
|
|
418
|
+
declare const createDefaultLogger: (name: string) => DirectLogger$1;
|
|
419
|
+
//#endregion
|
|
420
|
+
//#region src/artifacts/ArtifactManager.d.ts
|
|
421
|
+
declare const registerArtifacts: (app: Hono, artifacts: ReadonlyArray<ArtifactConfig>) => void;
|
|
422
|
+
//#endregion
|
|
423
|
+
//#region src/artifacts/DashboardArtifact.d.ts
|
|
424
|
+
declare const createDashboardArtifact: (getHealth: () => ServerHealth, getCapabilities: () => ServerCapabilities, getConnections: () => ReadonlyArray<GatewayInfo>) => ArtifactConfig;
|
|
425
|
+
//#endregion
|
|
426
|
+
//#region src/introspection/capabilitiesTool.d.ts
|
|
427
|
+
declare const createCapabilitiesTool: <T extends SessionAuth>(getCapabilities: () => ServerCapabilities) => Tool<T>;
|
|
428
|
+
//#endregion
|
|
429
|
+
//#region src/introspection/connectionsTool.d.ts
|
|
430
|
+
declare const createConnectionsTool: <T extends SessionAuth>(getConnections: () => ReadonlyArray<GatewayInfo>) => Tool<T>;
|
|
431
|
+
//#endregion
|
|
432
|
+
//#region src/introspection/healthTool.d.ts
|
|
433
|
+
declare const createHealthTool: <T extends SessionAuth>(getHealth: () => ServerHealth) => Tool<T>;
|
|
434
|
+
//#endregion
|
|
435
|
+
//#region src/gateway/Gateway.d.ts
|
|
436
|
+
declare const createGateway: (config: GatewayConfig, telemetry: TelemetryCollector) => GatewayInstance;
|
|
437
|
+
//#endregion
|
|
438
|
+
//#region src/gateway/GatewayManager.d.ts
|
|
439
|
+
declare const createGatewayManager: (telemetry: TelemetryCollector) => GatewayManagerInstance;
|
|
440
|
+
//#endregion
|
|
441
|
+
//#region src/gateway/toolProxy.d.ts
|
|
442
|
+
declare const createProxiedTools: <T extends SessionAuth>(gateway: GatewayInstance, telemetry?: TelemetryCollector) => ReadonlyArray<Tool<T>>;
|
|
443
|
+
//#endregion
|
|
444
|
+
export { type ArtifactConfig, type AudioContent, type BackendAdapter, type BackendFactory, type BackendSession, type CaptureLevel, type Completion, type Content, type ContentResult, type Context, type DirectLogger, type DirectoryArtifact, type DynamicArtifact, type EnrichedErrorResponse, type ErrorCategory, type GatewayConfig, type GatewayInfo, type GatewayInstance, type GatewayManagerInstance, type GatewayStatus, type ImageContent, type InferSchemaOutput, type JsonFileTelemetryOptions, type Logger, NoopTelemetry, type Progress, type Prompt, type PromptArgument, type PromptResult, type Resource, type ResourceContent, type ResourceLink, type ResourceResult, type SchemaParams, type ServerCapabilities, type ServerConfig, type ServerHealth, type ServerStatus, type SessionAuth, type SomaServerInstance, type SomaServerOptions, type StaticArtifact, type TelemetryCollector, type TelemetryEvent, type TelemetryEventType, type TextContent, type Tool, type ToolAnnotations, type ToolCaptureConfig, type ToolOptions, type TransportConfig, UserError, audioContent, classifyError, createCapabilitiesTool, createCompositeTelemetry, createConnectionsTool, createConsoleTelemetry, createDashboardArtifact, createDefaultLogger, createEnrichedError, createFastMCPBackend, createGateway, createGatewayManager, createHealthTool, createJsonFileTelemetry, createLogLayerTelemetry, createProxiedTools, createServer, imageContent, registerArtifacts, wrapPrompt, wrapResource, wrapTool };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import{Ref as e,Try as t}from"functype";import{FastMCP as n,ServerState as r}from"fastmcp";import{Client as i}from"@modelcontextprotocol/sdk/client/index.js";import{StreamableHTTPClientTransport as a}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{appendFile as o,mkdir as s,readFile as c}from"node:fs/promises";import{dirname as l,extname as u}from"node:path";import{createDirectConsoleLogger as d}from"functype-log";const f=(e,t)=>{for(let n of t)switch(n.type){case`static`:e.get(n.path,e=>e.body(n.content,{headers:{"Content-Type":n.contentType}}));break;case`dynamic`:e.get(n.path,e=>n.handler(e));break;case`directory`:break}},p=(e,t,n)=>({handler:()=>{let r=m(e(),t(),n());return new Response(r,{headers:{"Content-Type":`text/html; charset=utf-8`}})},path:`/dashboard`,type:`dynamic`}),m=(e,t,n)=>`<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>${e.name} - SomaMCP Dashboard</title>
|
|
7
|
+
<style>
|
|
8
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9
|
+
body { font-family: system-ui, -apple-system, sans-serif; background: #0a0a0a; color: #e0e0e0; padding: 2rem; }
|
|
10
|
+
h1 { font-size: 1.5rem; margin-bottom: 1.5rem; color: #fff; }
|
|
11
|
+
h2 { font-size: 1.1rem; margin-bottom: 0.75rem; color: #a0a0a0; text-transform: uppercase; letter-spacing: 0.05em; }
|
|
12
|
+
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; }
|
|
13
|
+
.card { background: #1a1a1a; border: 1px solid #2a2a2a; border-radius: 8px; padding: 1.25rem; }
|
|
14
|
+
.status { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.85rem; font-weight: 600; }
|
|
15
|
+
.status.running { background: #0a3d0a; color: #4ade80; }
|
|
16
|
+
.status.stopped { background: #3d0a0a; color: #f87171; }
|
|
17
|
+
.status.error { background: #3d2a0a; color: #fbbf24; }
|
|
18
|
+
.status.connected { background: #0a3d0a; color: #4ade80; }
|
|
19
|
+
.status.disconnected { background: #3d0a0a; color: #f87171; }
|
|
20
|
+
.metric { margin: 0.5rem 0; }
|
|
21
|
+
.metric-label { color: #888; font-size: 0.85rem; }
|
|
22
|
+
.metric-value { color: #fff; font-weight: 500; }
|
|
23
|
+
ul { list-style: none; }
|
|
24
|
+
li { padding: 0.35rem 0; border-bottom: 1px solid #222; font-size: 0.9rem; }
|
|
25
|
+
li:last-child { border-bottom: none; }
|
|
26
|
+
.desc { color: #888; font-size: 0.8rem; }
|
|
27
|
+
</style>
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<h1>${e.name}</h1>
|
|
31
|
+
<div class="grid">
|
|
32
|
+
<div class="card">
|
|
33
|
+
<h2>Health</h2>
|
|
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">${h(e.uptime)}</span></div>
|
|
36
|
+
<div class="metric"><span class="metric-label">Sessions:</span> <span class="metric-value">${e.activeSessions}</span></div>
|
|
37
|
+
<div class="metric"><span class="metric-label">Gateways:</span> <span class="metric-value">${e.gateways.connected}/${e.gateways.total}</span></div>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="card">
|
|
40
|
+
<h2>Tools (${t.tools.length})</h2>
|
|
41
|
+
<ul>${t.tools.map(e=>`<li><strong>${e.name}</strong>${e.description?` <span class="desc">${e.description}</span>`:``}</li>`).join(``)}</ul>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="card">
|
|
44
|
+
<h2>Resources (${t.resources.length})</h2>
|
|
45
|
+
<ul>${t.resources.map(e=>`<li><strong>${e.name}</strong> <span class="desc">${e.uri}</span></li>`).join(``)}</ul>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="card">
|
|
48
|
+
<h2>Prompts (${t.prompts.length})</h2>
|
|
49
|
+
<ul>${t.prompts.map(e=>`<li><strong>${e.name}</strong>${e.description?` <span class="desc">${e.description}</span>`:``}</li>`).join(``)}</ul>
|
|
50
|
+
</div>
|
|
51
|
+
${n.length>0?`<div class="card">
|
|
52
|
+
<h2>Gateways (${n.length})</h2>
|
|
53
|
+
<ul>${n.map(e=>`<li><strong>${e.name}</strong> <span class="status ${e.status}">${e.status}</span> <span class="desc">${e.url}</span></li>`).join(``)}</ul>
|
|
54
|
+
</div>`:``}
|
|
55
|
+
</div>
|
|
56
|
+
</body>
|
|
57
|
+
</html>`,h=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`},g=e=>{switch(e){case r.Running:return`running`;case r.Error:return`error`;default:return`stopped`}},_=(e,t)=>{let r=new n({...t,authenticate:e.authenticate,instructions:e.instructions,logger:e.logger,name:e.name,version:e.version});return{get serverState(){return g(r.serverState)},get sessions(){return r.sessions.map(e=>({sessionId:e.sessionId}))},addPrompt:e=>{r.addPrompt(e)},addResource:e=>{r.addResource(e)},addResourceTemplate:(...e)=>{r.addResourceTemplate(...e)},addTool:e=>{r.addTool(e)},getApp:()=>r.getApp(),on:(e,t)=>{r.on(e,t)},removePrompt:e=>r.removePrompt(e),removeResource:e=>r.removeResource(e),removeTool:e=>r.removeTool(e),start:async e=>{if(!e){await r.start();return}e.transportType===`httpStream`?await r.start({httpStream:e.httpStream,transportType:`httpStream`}):await r.start({transportType:`stdio`})},stop:()=>r.stop()}},v=(t,n)=>{let r=e(void 0),o=e(void 0),s=e([]),c=e(`disconnected`),l=e(void 0),u=t.name??t.id,d=()=>{let e=t.reconnectIntervalMs??5e3;l.set(setTimeout(()=>{f.connect()},e))},f={get config(){return t},get info(){return{id:t.id,name:u,remoteTools:s.get().map(e=>({description:e.description,name:e.name})),status:c.get(),url:t.url}},get name(){return u},get status(){return c.get()},get tools(){return s.get()},async callTool(e,n={}){let i=r.get();if(!i||c.get()!==`connected`)throw Error(`Gateway ${t.id} is not connected`);return await i.callTool({arguments:n,name:e})},async connect(){if(c.get()===`connected`)return;c.set(`connecting`);let e=Date.now();try{let l=new a(new URL(t.url));o.set(l);let d=new i({name:`soma-gateway-${t.id}`,version:`1.0.0`});r.set(d),await d.connect(l);let f=await d.listTools();s.set(f.tools),c.set(`connected`),n.recordEvent({data:{id:t.id,remoteToolCount:s.get().length,url:t.url},durationMs:Date.now()-e,name:u,timestamp:e,type:`gateway.connect`})}catch(r){c.set(`error`),n.recordEvent({data:{id:t.id,url:t.url},error:r instanceof Error?r.message:String(r),name:u,timestamp:e,type:`gateway.error`}),t.reconnect!==!1&&d()}},async disconnect(){let e=l.get();e&&(clearTimeout(e),l.set(void 0));let i=r.get();if(i)try{await i.close()}catch{}r.set(void 0),o.set(void 0),s.set([]),c.set(`disconnected`),n.recordEvent({data:{id:t.id},name:u,timestamp:Date.now(),type:`gateway.disconnect`})}};return f},y=e=>{let t=new Map;return{get connectedCount(){return[...t.values()].filter(e=>e.status===`connected`).length},get totalCount(){return t.size},add(n){let r=v(n,e);return t.set(n.id,r),r},async connectAll(){await Promise.allSettled([...t.values()].map(e=>e.connect()))},async disconnectAll(){await Promise.allSettled([...t.values()].map(e=>e.disconnect()))},get(e){return t.get(e)},getAll(){return[...t.values()]},getInfoAll(){return[...t.values()].map(e=>e.info)}}},b=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`},x=(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`]}},S=(e,t)=>{let n=b(e),r=e instanceof Error?e.message:String(e),i=x(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}},C=e=>t.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 C(e.callTool(r.name,i))).fold(n=>{let s=S(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}`}))},T=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`}),E=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`}),D=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`}),O=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)}}),k={flush:()=>Promise.resolve(),recordEvent:()=>{}},A=(e,t)=>!t||t.length===0?e:Object.fromEntries(Object.entries(e).map(([e,n])=>[e,t.includes(e)?`[REDACTED]`:n])),j=(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},M=e=>t.fromPromise(e),N=(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`?A(r,n?.redactInputFields):void 0;return(await M(e.execute(r,i))).fold(n=>{let r=S(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`?j(r,n?.maxOutputSize):void 0,requestId:s,sessionId:c,timestamp:o,type:`tool.execute`}),r))}}),P=(e,t)=>({...e,load:async n=>{let r=Date.now();return(await M(e.load(n))).fold(n=>{let i=S(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))}}),F=(e,t)=>({...e,load:async(n,r)=>{let i=Date.now();return(await M(e.load(n,r))).fold(n=>{let r=S(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))}}),I=t=>{let{artifacts:n,backendOptions:r,enableDashboard:i,enableIntrospection:a,gateways:o,logLayer:s,telemetry:c,...l}=t,u=l.name,d=c??(s?O(s):k),m=_(l,r),h=y(d),g=[],v=[],b=[],x=e(0);if(o)for(let e of o)h.add(e);let S=()=>{let e=x.get(),t=e>0?Date.now()-e:0;return{activeSessions:m.sessions.length,gateways:{connected:h.connectedCount,total:h.totalCount},name:u,startedAt:e,status:m.serverState,uptime:t}},C=()=>({prompts:b,resources:v,tools:g});a!==!1&&(m.addTool(D(()=>S())),m.addTool(T(()=>C())),m.addTool(E(()=>h.getInfoAll())));let A=[...n??[]];i!==!1&&A.push(p(()=>S(),()=>C(),()=>h.getInfoAll())),A.length>0&&f(m.getApp(),A),m.on(`connect`,({session:e})=>{d.recordEvent({data:{sessionId:e.sessionId},name:u,timestamp:Date.now(),type:`session.connect`})}),m.on(`disconnect`,({session:e})=>{d.recordEvent({data:{sessionId:e.sessionId},name:u,timestamp:Date.now(),type:`session.disconnect`})});let j=e=>{let t=N(e,d,`captureConfig`in e?e.captureConfig:void 0);m.addTool(t),g.push({description:e.description,name:e.name})},M=e=>{let t=P(e,d);m.addResource(t),v.push({description:e.description,name:e.name,uri:e.uri})},I=e=>{let t=F(e,d);m.addPrompt(t),b.push({description:e.description,name:e.name})};return{get name(){return u},get serverState(){return m.serverState},get sessions(){return m.sessions},addPrompt:I,addPrompts:e=>{for(let t of e)I(t)},addResource:M,addResources:e=>{for(let t of e)M(t)},addResourceTemplate:(...e)=>{m.addResourceTemplate(...e)},addTool:j,addTools:e=>{for(let t of e)j(t)},getApp:()=>m.getApp(),getCapabilities:C,getGatewayManager:()=>h,getHealth:S,removePrompt:e=>{m.removePrompt(e)},removeResource:e=>{m.removeResource(e)},removeTool:e=>{m.removeTool(e)},async start(e){x.set(Date.now()),d.recordEvent({name:u,timestamp:x.get(),type:`server.start`}),await m.start(e),await h.connectAll();for(let e of h.getAll())if(e.status===`connected`&&e.config.proxyTools!==!1){let t=w(e,d);for(let e of t)m.addTool(e)}},async stop(){await h.disconnectAll(),await m.stop(),d.recordEvent({name:u,timestamp:Date.now(),type:`server.stop`}),d.flush&&await d.flush()}}};var L=class extends Error{constructor(e){super(e),this.name=`UserError`}};const R={".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`},z={".aac":`audio/aac`,".flac":`audio/flac`,".m4a":`audio/mp4`,".mp3":`audio/mpeg`,".ogg":`audio/ogg`,".opus":`audio/opus`,".wav":`audio/wav`,".weba":`audio/webm`},B=(e,t,n)=>t[u(new URL(e,`file:///`).pathname).toLowerCase()]??n,V=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 c(e.path),source:e.path}:{data:e.buffer}},H=async e=>{let{data:t,source:n}=await V(e,`image`),r=n?B(n,R,`image/png`):`image/png`;return{data:t.toString(`base64`),mimeType:r,type:`image`}},U=async e=>{let{data:t,source:n}=await V(e,`audio`),r=n?B(n,z,`audio/mpeg`):`audio/mpeg`;return{data:t.toString(`base64`),mimeType:r,type:`audio`}},W=e=>({flush:async()=>{await Promise.all(e.map(e=>e.flush?e.flush():Promise.resolve()))},recordEvent:t=>{e.forEach(e=>e.recordEvent(t))}}),G=(e=`[soma]`)=>O(d({prefix:e})),K=t=>{let n=e([]),r=e(void 0),i=e(!1),a=async()=>{let e=n.getAndSet([]);if(e.length===0)return;i.get()||(await s(l(t.filePath),{recursive:!0}),i.set(!0));let r=`${e.map(e=>JSON.stringify(e)).join(`
|
|
58
|
+
`)}\n`;await o(t.filePath,r)},c=()=>{r.get()||r.set(setTimeout(()=>{r.set(void 0),a()},t.flushIntervalMs??1e3))};return{flush:async()=>{let e=r.get();e&&(clearTimeout(e),r.set(void 0)),await a()},recordEvent:e=>{n.update(t=>[...t,e]),c()}}},q=e=>d({prefix:`[${e}]`}).withContext({cell:e});export{k as NoopTelemetry,L as UserError,U as audioContent,b as classifyError,T as createCapabilitiesTool,W as createCompositeTelemetry,E as createConnectionsTool,G as createConsoleTelemetry,p as createDashboardArtifact,q as createDefaultLogger,S as createEnrichedError,_ as createFastMCPBackend,v as createGateway,y as createGatewayManager,D as createHealthTool,K as createJsonFileTelemetry,O as createLogLayerTelemetry,w as createProxiedTools,I as createServer,H as imageContent,f as registerArtifacts,F as wrapPrompt,P as wrapResource,N as wrapTool};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "somamcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Framework for building MCP servers with telemetry, introspection, and backend abstraction",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./backend": {
|
|
16
|
+
"types": "./dist/backend/index.d.ts",
|
|
17
|
+
"import": "./dist/backend/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"MCP",
|
|
25
|
+
"server",
|
|
26
|
+
"telemetry",
|
|
27
|
+
"introspection",
|
|
28
|
+
"backend-adapter"
|
|
29
|
+
],
|
|
30
|
+
"author": "Jordan Burke",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
34
|
+
"fastmcp": "^3.35.0",
|
|
35
|
+
"functype": "^0.56.0",
|
|
36
|
+
"functype-log": "^0.2.0",
|
|
37
|
+
"hono": "^4.12.12",
|
|
38
|
+
"zod": "^4.3.6"
|
|
39
|
+
},
|
|
40
|
+
"prettier": "ts-builds/prettier",
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^24.12.2",
|
|
43
|
+
"get-port-please": "^3.2.0",
|
|
44
|
+
"ts-builds": "^2.6.4",
|
|
45
|
+
"tsdown": "^0.21.7"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"validate": "ts-builds validate",
|
|
49
|
+
"format": "ts-builds format",
|
|
50
|
+
"format:check": "ts-builds format:check",
|
|
51
|
+
"lint": "ts-builds lint",
|
|
52
|
+
"lint:check": "ts-builds lint:check",
|
|
53
|
+
"typecheck": "ts-builds typecheck",
|
|
54
|
+
"test": "ts-builds test",
|
|
55
|
+
"test:watch": "ts-builds test:watch",
|
|
56
|
+
"test:coverage": "ts-builds test:coverage",
|
|
57
|
+
"build": "ts-builds build",
|
|
58
|
+
"dev": "ts-builds dev",
|
|
59
|
+
"clean": "rimraf dist"
|
|
60
|
+
}
|
|
61
|
+
}
|