agent-discover 1.3.8 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/README.md +34 -8
  3. package/agent-desk-plugin.json +10 -3
  4. package/dist/context.d.ts +2 -0
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +15 -0
  7. package/dist/context.js.map +1 -1
  8. package/dist/domain/log.d.ts +7 -3
  9. package/dist/domain/log.d.ts.map +1 -1
  10. package/dist/domain/log.js +15 -5
  11. package/dist/domain/log.js.map +1 -1
  12. package/dist/domain/presets.d.ts +30 -0
  13. package/dist/domain/presets.d.ts.map +1 -0
  14. package/dist/domain/presets.js +76 -0
  15. package/dist/domain/presets.js.map +1 -0
  16. package/dist/domain/proxy.d.ts +153 -0
  17. package/dist/domain/proxy.d.ts.map +1 -1
  18. package/dist/domain/proxy.js +396 -3
  19. package/dist/domain/proxy.js.map +1 -1
  20. package/dist/domain/sampling.d.ts +9 -0
  21. package/dist/domain/sampling.d.ts.map +1 -0
  22. package/dist/domain/sampling.js +68 -0
  23. package/dist/domain/sampling.js.map +1 -0
  24. package/dist/storage/database.js +21 -0
  25. package/dist/storage/database.js.map +1 -1
  26. package/dist/transport/rest.d.ts.map +1 -1
  27. package/dist/transport/rest.js +349 -0
  28. package/dist/transport/rest.js.map +1 -1
  29. package/dist/transport/ws.d.ts.map +1 -1
  30. package/dist/transport/ws.js +32 -0
  31. package/dist/transport/ws.js.map +1 -1
  32. package/dist/ui/app.js +16 -0
  33. package/dist/ui/index.html +3 -0
  34. package/dist/ui/markdown.js +102 -0
  35. package/dist/ui/schema-form.js +393 -0
  36. package/dist/ui/styles.css +724 -0
  37. package/dist/ui/tester-window.html +116 -0
  38. package/dist/ui/tester-window.js +153 -0
  39. package/dist/ui/tester.js +1412 -0
  40. package/package.json +1 -1
@@ -1,6 +1,90 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
4
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
1
5
  import type { SecretsService } from './secrets.js';
2
6
  import type { MetricsService } from './metrics.js';
3
7
  import type { LogService } from './log.js';
8
+ type AnyTransport = StdioClientTransport | SSEClientTransport | StreamableHTTPClientTransport;
9
+ export type ResourceEntry = {
10
+ uri: string;
11
+ name: string;
12
+ description?: string;
13
+ mimeType?: string;
14
+ size?: number;
15
+ };
16
+ export type ResourceTemplateEntry = {
17
+ uriTemplate: string;
18
+ name: string;
19
+ description?: string;
20
+ mimeType?: string;
21
+ };
22
+ export type PromptEntry = {
23
+ name: string;
24
+ description?: string;
25
+ arguments?: Array<{
26
+ name: string;
27
+ description?: string;
28
+ required?: boolean;
29
+ }>;
30
+ };
31
+ export type ServerInfo = {
32
+ name: string;
33
+ version: string;
34
+ instructions?: string;
35
+ capabilities: Record<string, unknown>;
36
+ };
37
+ interface ActiveServer {
38
+ client: Client;
39
+ transport: AnyTransport;
40
+ tools: Array<{
41
+ name: string;
42
+ description?: string;
43
+ inputSchema?: Record<string, unknown>;
44
+ }>;
45
+ config: ServerConfig;
46
+ capabilities?: Record<string, unknown>;
47
+ serverVersion?: {
48
+ name: string;
49
+ version: string;
50
+ };
51
+ instructions?: string;
52
+ transient: boolean;
53
+ interactive: boolean;
54
+ lastPingMs?: number;
55
+ }
56
+ export interface PendingElicitation {
57
+ id: string;
58
+ serverName: string;
59
+ message: string;
60
+ requestedSchema: Record<string, unknown>;
61
+ createdAt: number;
62
+ }
63
+ export type ElicitationAction = 'accept' | 'decline' | 'cancel';
64
+ export interface SamplingProvider {
65
+ createMessage(request: {
66
+ serverName: string;
67
+ messages: Array<{
68
+ role: string;
69
+ content: {
70
+ type: string;
71
+ text?: string;
72
+ };
73
+ }>;
74
+ maxTokens?: number;
75
+ temperature?: number;
76
+ systemPrompt?: string;
77
+ modelPreferences?: Record<string, unknown>;
78
+ }): Promise<{
79
+ role: 'assistant';
80
+ content: {
81
+ type: 'text';
82
+ text: string;
83
+ };
84
+ model: string;
85
+ stopReason?: string;
86
+ }>;
87
+ }
4
88
  export interface ServerConfig {
5
89
  name: string;
6
90
  command?: string;
@@ -19,13 +103,31 @@ export interface ParsedToolName {
19
103
  serverName: string;
20
104
  toolName: string;
21
105
  }
106
+ export interface TransientHandle {
107
+ handle: string;
108
+ serverName: string;
109
+ tools: ActiveServer['tools'];
110
+ capabilities: Record<string, unknown>;
111
+ serverVersion?: {
112
+ name: string;
113
+ version: string;
114
+ };
115
+ expiresAt: number;
116
+ }
22
117
  export declare class McpProxy {
23
118
  private readonly activeServers;
24
119
  private readonly activating;
120
+ private readonly transient;
121
+ private transientSeq;
25
122
  private secretsService?;
26
123
  private metricsService?;
27
124
  private logService?;
28
125
  private serverIdResolver?;
126
+ private rootsProvider;
127
+ private samplingProvider?;
128
+ private readonly elicitations;
129
+ private elicitationListener?;
130
+ private elicitationSeq;
29
131
  setSecretsService(secrets: SecretsService): void;
30
132
  setMetricsService(metrics: MetricsService): void;
31
133
  setLogService(logs: LogService): void;
@@ -35,6 +137,7 @@ export declare class McpProxy {
35
137
  description?: string;
36
138
  inputSchema?: Record<string, unknown>;
37
139
  }>>;
140
+ private activateInternal;
38
141
  deactivate(name: string): Promise<void>;
39
142
  callTool(serverName: string, toolName: string, args?: Record<string, unknown>): Promise<{
40
143
  content: Array<{
@@ -53,7 +156,57 @@ export declare class McpProxy {
53
156
  description?: string;
54
157
  }>;
55
158
  isActive(name: string): boolean;
159
+ getServerInfo(name: string): ServerInfo | null;
160
+ listToolsLive(name: string): Promise<ActiveServer['tools']>;
161
+ listResources(name: string, cursor?: string): Promise<{
162
+ resources: ResourceEntry[];
163
+ nextCursor?: string;
164
+ }>;
165
+ listResourceTemplates(name: string, cursor?: string): Promise<{
166
+ resourceTemplates: ResourceTemplateEntry[];
167
+ nextCursor?: string;
168
+ }>;
169
+ readResource(name: string, uri: string): Promise<{
170
+ contents: Array<Record<string, unknown>>;
171
+ }>;
172
+ subscribeResource(name: string, uri: string): Promise<void>;
173
+ unsubscribeResource(name: string, uri: string): Promise<void>;
174
+ listPrompts(name: string, cursor?: string): Promise<{
175
+ prompts: PromptEntry[];
176
+ nextCursor?: string;
177
+ }>;
178
+ getPrompt(name: string, promptName: string, args?: Record<string, string>): Promise<{
179
+ messages: Array<Record<string, unknown>>;
180
+ description?: string;
181
+ }>;
182
+ ping(name: string): Promise<{
183
+ ok: boolean;
184
+ rtt_ms: number;
185
+ }>;
186
+ setLoggingLevel(name: string, level: 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical' | 'alert' | 'emergency'): Promise<void>;
187
+ exportConfig(name: string, format: 'mcp-json' | 'agent-discover'): Record<string, unknown>;
188
+ activateTransient(config: ServerConfig, ttlMs?: number): Promise<TransientHandle>;
189
+ releaseTransient(handle: string): Promise<void>;
190
+ resolveTransient(handle: string): string | null;
191
+ private pruneTransient;
192
+ setRootsProvider(provider: () => Array<{
193
+ uri: string;
194
+ name?: string;
195
+ }>): void;
196
+ private wireRootsHandler;
197
+ private wireNotificationHandler;
198
+ private requireActive;
199
+ setElicitationListener(listener: (pending: PendingElicitation) => void): void;
200
+ listPendingElicitations(): PendingElicitation[];
201
+ respondElicitation(id: string, response: {
202
+ action: ElicitationAction;
203
+ content?: Record<string, unknown>;
204
+ }): boolean;
205
+ private wireElicitationHandler;
206
+ setSamplingProvider(provider: SamplingProvider): void;
207
+ private wireSamplingHandler;
56
208
  private createTransport;
57
209
  deactivateAll(): Promise<void>;
58
210
  }
211
+ export {};
59
212
  //# sourceMappingURL=proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/domain/proxy.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAwC3C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,iBAAiB,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IAKjE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,gBAAgB,CAAC,CAAkC;IAE3D,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIhD,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIhD,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAIrC,mBAAmB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,IAAI;IAI9D,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAC3C,KAAK,CAAC;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACvC,CAAC,CACH;IA6DK,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvC,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC;QACT,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IAoCF,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,SAAS;IAgBjB,kBAAkB,IAAI,WAAW,EAAE;IAcnC,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAgB5D,oBAAoB,IAAI,MAAM,EAAE;IAIhC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAK3E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,OAAO,CAAC,eAAe;IA2DjB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAUrC"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/domain/proxy.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
10
10
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
11
11
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
12
12
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
13
+ import { ElicitRequestSchema, CreateMessageRequestSchema, ListRootsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
13
14
  import { version } from '../version.js';
14
15
  const ACTIVATE_TIMEOUT_MS = 60_000;
15
16
  const CALL_TIMEOUT_MS = 60_000;
@@ -31,6 +32,9 @@ function withTimeout(promise, ms, label) {
31
32
  new Promise((_resolve, reject) => setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms)),
32
33
  ]);
33
34
  }
35
+ const TRANSIENT_TTL_MS = 15 * 60_000;
36
+ const TRANSIENT_NAME_PREFIX = '__transient__';
37
+ const ELICITATION_TIMEOUT_MS = 2 * 60_000;
34
38
  export class McpProxy {
35
39
  activeServers = new Map();
36
40
  // Names currently mid-activation. Held only across the connect/listTools
@@ -38,10 +42,17 @@ export class McpProxy {
38
42
  // child processes (the original `if (activeServers.has(name))` guard
39
43
  // races because both callers pass it before either awaits).
40
44
  activating = new Set();
45
+ transient = new Map();
46
+ transientSeq = 0;
41
47
  secretsService;
42
48
  metricsService;
43
49
  logService;
44
50
  serverIdResolver;
51
+ rootsProvider = () => [];
52
+ samplingProvider;
53
+ elicitations = new Map();
54
+ elicitationListener;
55
+ elicitationSeq = 0;
45
56
  setSecretsService(secrets) {
46
57
  this.secretsService = secrets;
47
58
  }
@@ -55,6 +66,9 @@ export class McpProxy {
55
66
  this.serverIdResolver = resolver;
56
67
  }
57
68
  async activate(config) {
69
+ return this.activateInternal(config, false, false);
70
+ }
71
+ async activateInternal(config, transient, interactive) {
58
72
  if (this.activeServers.has(config.name) || this.activating.has(config.name)) {
59
73
  throw new Error(`Server "${config.name}" is already active`);
60
74
  }
@@ -63,12 +77,42 @@ export class McpProxy {
63
77
  this.activating.add(config.name);
64
78
  try {
65
79
  const transport = this.createTransport(config);
66
- const client = new Client({ name: 'agent-discover', version }, { capabilities: {} });
80
+ const advertisedCapabilities = {
81
+ roots: { listChanged: true },
82
+ elicitation: {},
83
+ };
84
+ if (interactive) {
85
+ advertisedCapabilities.sampling = {};
86
+ }
87
+ const client = new Client({ name: 'agent-discover', version }, { capabilities: advertisedCapabilities });
88
+ this.wireRootsHandler(client);
89
+ this.wireNotificationHandler(client, config.name);
90
+ if (interactive) {
91
+ this.wireElicitationHandler(client, config.name);
92
+ this.wireSamplingHandler(client, config.name);
93
+ }
67
94
  try {
68
95
  await withTimeout(client.connect(transport), ACTIVATE_TIMEOUT_MS, 'connect');
96
+ const capabilities = typeof client.getServerCapabilities === 'function'
97
+ ? client.getServerCapabilities()
98
+ : undefined;
99
+ const serverVersion = typeof client.getServerVersion === 'function' ? client.getServerVersion() : undefined;
100
+ const instructions = typeof client.getInstructions === 'function' ? client.getInstructions() : undefined;
69
101
  const result = await withTimeout(client.listTools(), ACTIVATE_TIMEOUT_MS, 'listTools');
70
102
  const tools = result.tools ?? [];
71
- this.activeServers.set(config.name, { client, transport, tools, config });
103
+ this.activeServers.set(config.name, {
104
+ client,
105
+ transport,
106
+ tools,
107
+ config,
108
+ capabilities: capabilities,
109
+ serverVersion: serverVersion
110
+ ? { name: serverVersion.name, version: serverVersion.version }
111
+ : undefined,
112
+ instructions,
113
+ transient,
114
+ interactive,
115
+ });
72
116
  return tools;
73
117
  }
74
118
  catch (err) {
@@ -131,8 +175,19 @@ export class McpProxy {
131
175
  if (!server)
132
176
  throw new Error(`Server "${serverName}" is not active`);
133
177
  const start = Date.now();
178
+ const logs = this.logService;
179
+ const onprogress = (notification) => {
180
+ try {
181
+ logs?.pushProgress(serverName, notification.progressToken ?? toolName, notification.progress ?? 0, notification.total, notification.message);
182
+ }
183
+ catch {
184
+ /* ignore */
185
+ }
186
+ };
134
187
  try {
135
- const result = await withTimeout(server.client.callTool({ name: toolName, arguments: args ?? {} }), CALL_TIMEOUT_MS, `${serverName}/${toolName}`);
188
+ const result = await withTimeout(server.client.callTool({ name: toolName, arguments: args ?? {} }, undefined, {
189
+ onprogress,
190
+ }), CALL_TIMEOUT_MS, `${serverName}/${toolName}`);
136
191
  const typed = result;
137
192
  const latency = Date.now() - start;
138
193
  const success = !typed.isError;
@@ -215,6 +270,344 @@ export class McpProxy {
215
270
  isActive(name) {
216
271
  return this.activeServers.has(name);
217
272
  }
273
+ // ---------------------------------------------------------------------------
274
+ // Tester surface — server info, resources, prompts, ping, logging level
275
+ // ---------------------------------------------------------------------------
276
+ getServerInfo(name) {
277
+ const server = this.activeServers.get(name);
278
+ if (!server)
279
+ return null;
280
+ return {
281
+ name: server.serverVersion?.name ?? server.config.name,
282
+ version: server.serverVersion?.version ?? '',
283
+ instructions: server.instructions,
284
+ capabilities: server.capabilities ?? {},
285
+ };
286
+ }
287
+ async listToolsLive(name) {
288
+ const server = this.requireActive(name);
289
+ const result = await withTimeout(server.client.listTools(), CALL_TIMEOUT_MS, 'listTools');
290
+ const tools = result.tools ?? [];
291
+ server.tools = tools;
292
+ return tools;
293
+ }
294
+ async listResources(name, cursor) {
295
+ const server = this.requireActive(name);
296
+ const params = cursor ? { cursor } : undefined;
297
+ const result = await withTimeout(server.client.listResources(params), CALL_TIMEOUT_MS, 'listResources');
298
+ return {
299
+ resources: (result.resources ?? []).map((r) => ({
300
+ uri: r.uri,
301
+ name: r.name,
302
+ description: r.description,
303
+ mimeType: r.mimeType,
304
+ size: r.size,
305
+ })),
306
+ nextCursor: result.nextCursor,
307
+ };
308
+ }
309
+ async listResourceTemplates(name, cursor) {
310
+ const server = this.requireActive(name);
311
+ const params = cursor ? { cursor } : undefined;
312
+ const result = await withTimeout(server.client.listResourceTemplates(params), CALL_TIMEOUT_MS, 'listResourceTemplates');
313
+ return {
314
+ resourceTemplates: (result.resourceTemplates ?? []).map((t) => ({
315
+ uriTemplate: t.uriTemplate,
316
+ name: t.name,
317
+ description: t.description,
318
+ mimeType: t.mimeType,
319
+ })),
320
+ nextCursor: result.nextCursor,
321
+ };
322
+ }
323
+ async readResource(name, uri) {
324
+ const server = this.requireActive(name);
325
+ const start = Date.now();
326
+ try {
327
+ const result = await withTimeout(server.client.readResource({ uri }), CALL_TIMEOUT_MS, `${name}/readResource`);
328
+ const latency = Date.now() - start;
329
+ this.logService?.push(name, uri, { uri }, JSON.stringify(result.contents), latency, true, 'resource-read');
330
+ return { contents: result.contents };
331
+ }
332
+ catch (err) {
333
+ const latency = Date.now() - start;
334
+ const msg = err instanceof Error ? err.message : String(err);
335
+ this.logService?.push(name, uri, { uri }, msg, latency, false, 'resource-read');
336
+ throw err;
337
+ }
338
+ }
339
+ async subscribeResource(name, uri) {
340
+ const server = this.requireActive(name);
341
+ await withTimeout(server.client.subscribeResource({ uri }), CALL_TIMEOUT_MS, 'subscribe');
342
+ }
343
+ async unsubscribeResource(name, uri) {
344
+ const server = this.requireActive(name);
345
+ await withTimeout(server.client.unsubscribeResource({ uri }), CALL_TIMEOUT_MS, 'unsubscribe');
346
+ }
347
+ async listPrompts(name, cursor) {
348
+ const server = this.requireActive(name);
349
+ const params = cursor ? { cursor } : undefined;
350
+ const result = await withTimeout(server.client.listPrompts(params), CALL_TIMEOUT_MS, 'listPrompts');
351
+ return {
352
+ prompts: (result.prompts ?? []).map((p) => ({
353
+ name: p.name,
354
+ description: p.description,
355
+ arguments: p.arguments,
356
+ })),
357
+ nextCursor: result.nextCursor,
358
+ };
359
+ }
360
+ async getPrompt(name, promptName, args) {
361
+ const server = this.requireActive(name);
362
+ const start = Date.now();
363
+ try {
364
+ const result = await withTimeout(server.client.getPrompt({ name: promptName, arguments: args ?? {} }), CALL_TIMEOUT_MS, `${name}/getPrompt/${promptName}`);
365
+ const latency = Date.now() - start;
366
+ this.logService?.push(name, promptName, (args ?? {}), JSON.stringify(result.messages), latency, true, 'prompt-get');
367
+ return {
368
+ messages: result.messages,
369
+ description: result.description,
370
+ };
371
+ }
372
+ catch (err) {
373
+ const latency = Date.now() - start;
374
+ const msg = err instanceof Error ? err.message : String(err);
375
+ this.logService?.push(name, promptName, (args ?? {}), msg, latency, false, 'prompt-get');
376
+ throw err;
377
+ }
378
+ }
379
+ async ping(name) {
380
+ const server = this.requireActive(name);
381
+ const start = Date.now();
382
+ try {
383
+ await withTimeout(server.client.ping(), CALL_TIMEOUT_MS, 'ping');
384
+ const rtt = Date.now() - start;
385
+ server.lastPingMs = rtt;
386
+ this.logService?.push(name, 'ping', {}, 'pong', rtt, true, 'ping');
387
+ return { ok: true, rtt_ms: rtt };
388
+ }
389
+ catch (err) {
390
+ const rtt = Date.now() - start;
391
+ const msg = err instanceof Error ? err.message : String(err);
392
+ this.logService?.push(name, 'ping', {}, msg, rtt, false, 'ping');
393
+ throw err;
394
+ }
395
+ }
396
+ async setLoggingLevel(name, level) {
397
+ const server = this.requireActive(name);
398
+ await withTimeout(server.client.setLoggingLevel(level), CALL_TIMEOUT_MS, 'setLoggingLevel');
399
+ }
400
+ exportConfig(name, format) {
401
+ const server = this.activeServers.get(name);
402
+ if (!server)
403
+ throw new Error(`Server "${name}" is not active`);
404
+ const cfg = server.config;
405
+ const entry = {};
406
+ if (cfg.transport === 'sse' || cfg.transport === 'streamable-http') {
407
+ entry.type = cfg.transport === 'sse' ? 'sse' : 'http';
408
+ if (cfg.url)
409
+ entry.url = cfg.url;
410
+ if (cfg.headers && Object.keys(cfg.headers).length > 0)
411
+ entry.headers = cfg.headers;
412
+ }
413
+ else {
414
+ if (cfg.command)
415
+ entry.command = cfg.command;
416
+ if (cfg.args && cfg.args.length > 0)
417
+ entry.args = cfg.args;
418
+ if (cfg.env && Object.keys(cfg.env).length > 0)
419
+ entry.env = cfg.env;
420
+ }
421
+ if (format === 'agent-discover') {
422
+ return { servers: [{ name: cfg.name, ...entry, auto_activate: true }] };
423
+ }
424
+ return { mcpServers: { [cfg.name]: entry } };
425
+ }
426
+ // ---------------------------------------------------------------------------
427
+ // Transient (ad-hoc) servers
428
+ // ---------------------------------------------------------------------------
429
+ async activateTransient(config, ttlMs = TRANSIENT_TTL_MS) {
430
+ this.pruneTransient();
431
+ const handle = `${Date.now().toString(36)}-${(++this.transientSeq).toString(36)}`;
432
+ const serverName = `${TRANSIENT_NAME_PREFIX}${handle}`;
433
+ const merged = { ...config, name: serverName };
434
+ const tools = await this.activateInternal(merged, true, true);
435
+ const expiresAt = Date.now() + ttlMs;
436
+ this.transient.set(handle, { serverName, expiresAt });
437
+ const active = this.activeServers.get(serverName);
438
+ setTimeout(() => {
439
+ this.releaseTransient(handle).catch(() => { });
440
+ }, ttlMs).unref?.();
441
+ return {
442
+ handle,
443
+ serverName,
444
+ tools,
445
+ capabilities: active.capabilities ?? {},
446
+ serverVersion: active.serverVersion,
447
+ expiresAt,
448
+ };
449
+ }
450
+ async releaseTransient(handle) {
451
+ const entry = this.transient.get(handle);
452
+ if (!entry)
453
+ return;
454
+ this.transient.delete(handle);
455
+ if (this.activeServers.has(entry.serverName)) {
456
+ try {
457
+ await this.deactivate(entry.serverName);
458
+ }
459
+ catch {
460
+ /* ignore */
461
+ }
462
+ }
463
+ }
464
+ resolveTransient(handle) {
465
+ const entry = this.transient.get(handle);
466
+ if (!entry)
467
+ return null;
468
+ if (entry.expiresAt < Date.now()) {
469
+ this.releaseTransient(handle).catch(() => { });
470
+ return null;
471
+ }
472
+ return entry.serverName;
473
+ }
474
+ pruneTransient() {
475
+ const now = Date.now();
476
+ for (const [handle, entry] of this.transient.entries()) {
477
+ if (entry.expiresAt < now) {
478
+ this.releaseTransient(handle).catch(() => { });
479
+ }
480
+ }
481
+ }
482
+ // ---------------------------------------------------------------------------
483
+ // Roots provider (advertises client roots capability)
484
+ // ---------------------------------------------------------------------------
485
+ setRootsProvider(provider) {
486
+ this.rootsProvider = provider;
487
+ }
488
+ wireRootsHandler(client) {
489
+ try {
490
+ client.setRequestHandler(ListRootsRequestSchema, async () => ({
491
+ roots: this.rootsProvider(),
492
+ }));
493
+ }
494
+ catch {
495
+ /* roots handler is best-effort; failures don't block activation */
496
+ }
497
+ }
498
+ wireNotificationHandler(client, serverName) {
499
+ const anyClient = client;
500
+ const logs = this.logService;
501
+ anyClient.fallbackNotificationHandler = async (n) => {
502
+ try {
503
+ if (!logs)
504
+ return;
505
+ if (n.method === 'notifications/progress' && n.params) {
506
+ const p = n.params;
507
+ logs.pushProgress(serverName, p.progressToken ?? 0, p.progress ?? 0, p.total, p.message);
508
+ }
509
+ else {
510
+ logs.pushNotification(serverName, n.method, (n.params ?? {}));
511
+ }
512
+ }
513
+ catch {
514
+ /* ignore */
515
+ }
516
+ };
517
+ }
518
+ requireActive(name) {
519
+ const server = this.activeServers.get(name);
520
+ if (!server)
521
+ throw new Error(`Server "${name}" is not active`);
522
+ return server;
523
+ }
524
+ // ---------------------------------------------------------------------------
525
+ // Elicitation — only wired on interactive (transient) clients
526
+ // ---------------------------------------------------------------------------
527
+ setElicitationListener(listener) {
528
+ this.elicitationListener = listener;
529
+ }
530
+ listPendingElicitations() {
531
+ return [...this.elicitations.values()].map((e) => e.request);
532
+ }
533
+ respondElicitation(id, response) {
534
+ const entry = this.elicitations.get(id);
535
+ if (!entry)
536
+ return false;
537
+ this.elicitations.delete(id);
538
+ clearTimeout(entry.timer);
539
+ entry.resolve(response);
540
+ return true;
541
+ }
542
+ wireElicitationHandler(client, serverName) {
543
+ client.setRequestHandler(ElicitRequestSchema, async (req) => {
544
+ const params = req.params;
545
+ const id = `elicit-${Date.now().toString(36)}-${(++this.elicitationSeq).toString(36)}`;
546
+ const pending = {
547
+ id,
548
+ serverName,
549
+ message: params.message ?? '',
550
+ requestedSchema: params.requestedSchema ?? { type: 'object', properties: {} },
551
+ createdAt: Date.now(),
552
+ };
553
+ this.logService?.push(serverName, 'elicitation/create', pending.requestedSchema, pending.message, 0, true, 'elicitation');
554
+ return new Promise((resolve) => {
555
+ const timer = setTimeout(() => {
556
+ if (this.elicitations.has(id)) {
557
+ this.elicitations.delete(id);
558
+ resolve({ action: 'cancel' });
559
+ }
560
+ }, ELICITATION_TIMEOUT_MS);
561
+ this.elicitations.set(id, { serverName, resolve, timer, request: pending });
562
+ try {
563
+ this.elicitationListener?.(pending);
564
+ }
565
+ catch {
566
+ /* ignore listener errors */
567
+ }
568
+ }).then((response) => {
569
+ return response.action === 'accept' && response.content
570
+ ? { action: 'accept', content: response.content }
571
+ : { action: response.action };
572
+ });
573
+ });
574
+ }
575
+ // ---------------------------------------------------------------------------
576
+ // Sampling — only wired on interactive (transient) clients
577
+ // ---------------------------------------------------------------------------
578
+ setSamplingProvider(provider) {
579
+ this.samplingProvider = provider;
580
+ }
581
+ wireSamplingHandler(client, serverName) {
582
+ client.setRequestHandler(CreateMessageRequestSchema, async (req) => {
583
+ const params = req.params;
584
+ const start = Date.now();
585
+ if (!this.samplingProvider) {
586
+ const message = 'sampling/createMessage: no sampling provider configured (set AGENT_DISCOVER_OPENAI_API_KEY or OPENAI_API_KEY to enable)';
587
+ this.logService?.push(serverName, 'sampling/createMessage', params, message, 0, false, 'sampling');
588
+ throw new Error(message);
589
+ }
590
+ try {
591
+ const result = await this.samplingProvider.createMessage({
592
+ serverName,
593
+ messages: params.messages,
594
+ maxTokens: params.maxTokens,
595
+ temperature: params.temperature,
596
+ systemPrompt: params.systemPrompt,
597
+ modelPreferences: params.modelPreferences,
598
+ });
599
+ const latency = Date.now() - start;
600
+ this.logService?.push(serverName, 'sampling/createMessage', params, result.content.text, latency, true, 'sampling');
601
+ return result;
602
+ }
603
+ catch (err) {
604
+ const latency = Date.now() - start;
605
+ const msg = err instanceof Error ? err.message : String(err);
606
+ this.logService?.push(serverName, 'sampling/createMessage', params, msg, latency, false, 'sampling');
607
+ throw err;
608
+ }
609
+ });
610
+ }
218
611
  createTransport(config) {
219
612
  const transportType = config.transport ?? 'stdio';
220
613
  if ((transportType === 'streamable-http' || transportType === 'sse') && config.url) {