agent-discover 1.0.18 → 1.0.20

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.
@@ -2,7 +2,7 @@
2
2
  "id": "agent-discover",
3
3
  "name": "Discover",
4
4
  "icon": "explore",
5
- "version": "1.0.18",
5
+ "version": "1.0.20",
6
6
  "description": "MCP server registry — browse, install, configure, monitor",
7
7
  "ui": "./dist/ui/app.js",
8
8
  "css": "./dist/ui/styles.css",
package/dist/index.js CHANGED
@@ -2,23 +2,23 @@
2
2
  // =============================================================================
3
3
  // agent-discover — MCP server entry point (stdio transport)
4
4
  //
5
- // Communicates via JSON-RPC over stdin/stdout.
6
- // Auto-starts the dashboard HTTP server via leader election.
5
+ // Communicates via JSON-RPC over stdin/stdout via agent-common's startMcpServer.
6
+ // Dynamic tool list (regenerated per request so proxied child-server tools
7
+ // stay current), auto-starts dashboard on initialize, and emits
8
+ // `notifications/tools/list_changed` after tool calls that alter active
9
+ // servers (activate/deactivate/uninstall).
7
10
  // =============================================================================
8
- import { createInterface } from 'readline';
11
+ import { startMcpServer } from 'agent-common';
9
12
  import { createContext } from './context.js';
10
13
  import { readPackageMeta } from './package-meta.js';
11
14
  import { createToolHandler, getToolList } from './transport/mcp.js';
12
15
  import { startDashboard } from './server.js';
13
- import { RegistryError } from './types.js';
14
16
  const SERVER_INFO = readPackageMeta();
15
- const CAPABILITIES = { tools: { listChanged: true } };
16
17
  const DASHBOARD_PORT = parseInt(process.env.AGENT_DISCOVER_PORT ?? '3424', 10);
17
18
  const appContext = createContext();
18
19
  const handleTool = createToolHandler(appContext);
19
20
  let dashboard = null;
20
21
  let dashboardAttempted = false;
21
- let toolsChanged = false;
22
22
  function tryStartDashboard() {
23
23
  if (dashboard || dashboardAttempted)
24
24
  return;
@@ -31,111 +31,19 @@ function tryStartDashboard() {
31
31
  process.stderr.write(`[agent-discover] Dashboard port ${DASHBOARD_PORT} in use — another instance is serving.\n`);
32
32
  });
33
33
  }
34
- function writeJsonRpcResponse(response) {
35
- process.stdout.write(JSON.stringify(response) + '\n');
36
- }
37
- function sendToolsChangedNotification() {
38
- if (toolsChanged) {
39
- toolsChanged = false;
40
- process.stdout.write(JSON.stringify({
41
- jsonrpc: '2.0',
42
- method: 'notifications/tools/list_changed',
43
- }) + '\n');
44
- }
45
- }
46
- async function handleRequest(request) {
47
- const { method, params, id } = request;
48
- switch (method) {
49
- case 'initialize':
50
- tryStartDashboard();
51
- return {
52
- jsonrpc: '2.0',
53
- id,
54
- result: {
55
- protocolVersion: '2024-11-05',
56
- serverInfo: SERVER_INFO,
57
- capabilities: CAPABILITIES,
58
- },
59
- };
60
- case 'notifications/initialized':
61
- return null;
62
- case 'tools/list':
63
- return { jsonrpc: '2.0', id, result: { tools: getToolList(appContext) } };
64
- case 'tools/call': {
65
- const toolName = String(params?.name ?? '');
66
- const rawArgs = params?.arguments;
67
- const toolArgs = typeof rawArgs === 'object' && rawArgs !== null && !Array.isArray(rawArgs)
68
- ? rawArgs
69
- : {};
70
- try {
71
- const result = await handleTool(toolName, toolArgs);
72
- if (toolName === 'registry' &&
73
- (toolArgs.action === 'activate' ||
74
- toolArgs.action === 'deactivate' ||
75
- toolArgs.action === 'uninstall')) {
76
- toolsChanged = true;
77
- }
78
- const response = {
79
- jsonrpc: '2.0',
80
- id,
81
- result: {
82
- content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
83
- },
84
- };
85
- return response;
86
- }
87
- catch (err) {
88
- const message = err instanceof Error ? err.message : String(err);
89
- const code = err instanceof RegistryError ? err.code : 'UNKNOWN_ERROR';
90
- return {
91
- jsonrpc: '2.0',
92
- id,
93
- result: {
94
- content: [{ type: 'text', text: `Error [${code}]: ${message}` }],
95
- isError: true,
96
- },
97
- };
98
- }
34
+ startMcpServer({
35
+ serverInfo: SERVER_INFO,
36
+ tools: () => getToolList(appContext),
37
+ handleTool,
38
+ onInitialize: tryStartDashboard,
39
+ capabilities: { tools: { listChanged: true } },
40
+ onToolCalled: (name, args, notify) => {
41
+ if (name === 'registry' &&
42
+ (args.action === 'activate' || args.action === 'deactivate' || args.action === 'uninstall')) {
43
+ notify('notifications/tools/list_changed');
99
44
  }
100
- case 'ping':
101
- return { jsonrpc: '2.0', id, result: {} };
102
- default:
103
- return {
104
- jsonrpc: '2.0',
105
- id,
106
- error: { code: -32601, message: `Method not found: ${method}` },
107
- };
108
- }
109
- }
110
- const stdioReadline = createInterface({ input: process.stdin, terminal: false });
111
- stdioReadline.on('line', (line) => {
112
- if (!line.trim())
113
- return;
114
- try {
115
- const request = JSON.parse(line);
116
- handleRequest(request)
117
- .then((response) => {
118
- if (response) {
119
- writeJsonRpcResponse(response);
120
- sendToolsChangedNotification();
121
- }
122
- })
123
- .catch((err) => {
124
- process.stderr.write('[agent-discover] Handler error: ' +
125
- (err instanceof Error ? err.message : String(err)) +
126
- '\n');
127
- });
128
- }
129
- catch (err) {
130
- process.stderr.write('[agent-discover] JSON-RPC parse error: ' +
131
- (err instanceof Error ? err.message : String(err)) +
132
- '\n');
133
- writeJsonRpcResponse({
134
- jsonrpc: '2.0',
135
- id: null,
136
- error: { code: -32700, message: 'Parse error' },
137
- });
138
- }
45
+ },
46
+ logLabel: 'agent-discover',
139
47
  });
140
48
  function cleanup() {
141
49
  if (dashboard) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,gFAAgF;AAChF,4DAA4D;AAC5D,EAAE;AACF,iFAAiF;AACjF,2EAA2E;AAC3E,gEAAgE;AAChE,wEAAwE;AACxE,2CAA2C;AAC3C,gFAAgF;AAEhF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAEnE,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;AACtC,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAE/E,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;AACnC,MAAM,UAAU,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;AAEjD,IAAI,SAAS,GAA2B,IAAI,CAAC;AAC7C,IAAI,kBAAkB,GAAG,KAAK,CAAC;AAE/B,SAAS,iBAAiB;IACxB,IAAI,SAAS,IAAI,kBAAkB;QAAE,OAAO;IAC5C,kBAAkB,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC;SACvC,IAAI,CAAC,CAAC,eAAe,EAAE,EAAE;QACxB,SAAS,GAAG,eAAe,CAAC;IAC9B,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mCAAmC,cAAc,0CAA0C,CAC5F,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC;AAED,cAAc,CAAC;IACb,UAAU,EAAE,WAAW;IACvB,KAAK,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC;IACpC,UAAU;IACV,YAAY,EAAE,iBAAiB;IAC/B,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;IAC9C,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QACnC,IACE,IAAI,KAAK,UAAU;YACnB,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,EAC3F,CAAC;YACD,MAAM,CAAC,kCAAkC,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IACD,QAAQ,EAAE,gBAAgB;CAC3B,CAAC,CAAC;AAEH,SAAS,OAAO;IACd,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,KAAK,EAAE,CAAC;QAClB,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,UAAU,CAAC,KAAK,EAAE,CAAC;AACrB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,EAAE,CAAC;IACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,EAAE,CAAC;IACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
@@ -1,9 +1,6 @@
1
- import { WebSocketServer } from 'ws';
1
+ import { type WsHandle } from 'agent-common';
2
2
  import type { Server } from 'http';
3
3
  import type { AppContext } from '../context.js';
4
- export interface WebSocketHandle {
5
- wss: WebSocketServer;
6
- close(): void;
7
- }
4
+ export type WebSocketHandle = WsHandle;
8
5
  export declare function setupWebSocket(httpServer: Server, ctx: AppContext): WebSocketHandle;
9
6
  //# sourceMappingURL=ws.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/transport/ws.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAa,MAAM,IAAI,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQhD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,eAAe,CAAC;IACrB,KAAK,IAAI,IAAI,CAAC;CACf;AAOD,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,eAAe,CAkGnF"}
1
+ {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/transport/ws.ts"],"names":[],"mappings":"AAQA,OAAO,EAAuC,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;AAEvC,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,eAAe,CAsBnF"}
@@ -1,146 +1,42 @@
1
1
  // =============================================================================
2
2
  // agent-discover — WebSocket transport
3
3
  //
4
- // Real-time state streaming to connected dashboard clients.
5
- // Full state on connect, delta updates via DB polling.
4
+ // Thin wrapper around agent-common's setupWebSocket. Streams full state with
5
+ // a single fingerprint (servers+active count). Both categories return the
6
+ // full payload so any DB change refreshes all connected clients.
6
7
  // =============================================================================
7
- import { WebSocketServer, WebSocket } from 'ws';
8
+ import { setupWebSocket as setupKitWebSocket } from 'agent-common';
8
9
  import { version } from '../version.js';
9
- const MAX_WS_MESSAGE_SIZE = 4096;
10
- const MAX_WS_CONNECTIONS = 50;
11
- const PING_INTERVAL_MS = 30_000;
12
- const DB_POLL_INTERVAL_MS = 2_000;
13
10
  export function setupWebSocket(httpServer, ctx) {
14
- const wss = new WebSocketServer({
15
- server: httpServer,
16
- maxPayload: MAX_WS_MESSAGE_SIZE,
17
- });
18
- const clients = new Map();
19
- wss.on('connection', (ws) => {
20
- if (wss.clients.size > MAX_WS_CONNECTIONS) {
21
- ws.close(1013, 'Too many connections');
22
- return;
23
- }
24
- clients.set(ws, { alive: true, fingerprint: null });
25
- sendFullState(ws, ctx, clients);
26
- ws.on('pong', () => {
27
- const clientState = clients.get(ws);
28
- if (clientState)
29
- clientState.alive = true;
30
- });
31
- ws.on('message', (raw) => {
32
- let parsed;
33
- try {
34
- parsed = JSON.parse(raw.toString());
35
- }
36
- catch {
37
- ws.send(JSON.stringify({ type: 'error', message: 'Invalid JSON' }));
38
- return;
39
- }
40
- if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
41
- ws.send(JSON.stringify({
42
- type: 'error',
43
- message: 'Message must be a JSON object',
44
- }));
45
- return;
46
- }
47
- const msg = parsed;
48
- if (msg.type === 'refresh') {
49
- const clientState = clients.get(ws);
50
- if (clientState)
51
- clientState.fingerprint = null;
52
- sendFullState(ws, ctx, clients);
53
- }
54
- });
55
- ws.on('error', () => clients.delete(ws));
56
- ws.on('close', () => clients.delete(ws));
57
- });
58
- const pingInterval = setInterval(() => {
59
- for (const [ws, state] of clients) {
60
- if (!state.alive) {
61
- ws.terminate();
62
- clients.delete(ws);
63
- continue;
64
- }
65
- state.alive = false;
66
- ws.ping();
67
- }
68
- }, PING_INTERVAL_MS);
69
- pingInterval.unref();
70
- const dbPollInterval = setInterval(() => {
71
- if (clients.size === 0)
72
- return;
73
- try {
74
- const fp = getFingerprint(ctx);
75
- for (const [ws, clientState] of clients) {
76
- if (ws.readyState !== WebSocket.OPEN)
77
- continue;
78
- if (clientState.fingerprint !== fp) {
79
- sendFullState(ws, ctx, clients);
80
- }
81
- }
82
- }
83
- catch (err) {
84
- process.stderr.write('[agent-discover] WS DB poll error: ' +
85
- (err instanceof Error ? err.message : String(err)) +
86
- '\n');
87
- }
88
- }, DB_POLL_INTERVAL_MS);
89
- dbPollInterval.unref();
90
- return {
91
- wss,
92
- close() {
93
- clearInterval(pingInterval);
94
- clearInterval(dbPollInterval);
95
- for (const [ws] of clients) {
96
- ws.close(1001, 'Server shutting down');
97
- }
98
- clients.clear();
99
- wss.close();
11
+ return setupKitWebSocket({
12
+ httpServer,
13
+ getFingerprints: () => {
14
+ const row = ctx.db.queryOne(`SELECT
15
+ COALESCE((SELECT COUNT(*) FROM servers), 0)
16
+ || ':' || COALESCE((SELECT MAX(id) FROM servers), 0)
17
+ || ':' || COALESCE((SELECT MAX(updated_at) FROM servers), '')
18
+ || ':' || COALESCE((SELECT COUNT(*) FROM server_tools), 0)
19
+ AS fp`);
20
+ const active = ctx.proxy.getActiveServerNames().length;
21
+ return { registry: (row?.fp ?? '') + ':' + active };
100
22
  },
101
- };
102
- }
103
- // ---------------------------------------------------------------------------
104
- // State helpers
105
- // ---------------------------------------------------------------------------
106
- function getFingerprint(ctx) {
107
- const row = ctx.db.queryOne(`SELECT
108
- COALESCE((SELECT COUNT(*) FROM servers), 0)
109
- || ':' || COALESCE((SELECT MAX(id) FROM servers), 0)
110
- || ':' || COALESCE((SELECT MAX(updated_at) FROM servers), '')
111
- || ':' || COALESCE((SELECT COUNT(*) FROM server_tools), 0)
112
- AS fp`);
113
- const activeCount = ctx.proxy.getActiveServerNames().length;
114
- return (row?.fp ?? '') + ':' + activeCount;
23
+ getCategoryData: () => buildStatePayload(ctx),
24
+ getFullState: () => ({ version, ...buildStatePayload(ctx) }),
25
+ logError: (err) => process.stderr.write('[agent-discover] WS error: ' + (err instanceof Error ? err.message : String(err)) + '\n'),
26
+ });
115
27
  }
116
- function sendFullState(ws, ctx, clients) {
117
- try {
118
- const fp = getFingerprint(ctx);
119
- const clientState = clients.get(ws);
120
- if (clientState)
121
- clientState.fingerprint = fp;
122
- const servers = ctx.registry.list();
123
- const serversWithStatus = servers.map((s) => ({
124
- ...s,
125
- active: ctx.proxy.isActive(s.name),
126
- tools: ctx.registry.getTools(s.id),
127
- }));
128
- const activeNames = ctx.proxy.getActiveServerNames();
129
- const activeServers = activeNames.map((name) => ({
130
- name,
131
- tools: ctx.proxy.getServerTools(name),
132
- }));
133
- ws.send(JSON.stringify({
134
- type: 'state',
135
- version,
136
- servers: serversWithStatus,
137
- active: activeServers,
138
- }));
139
- }
140
- catch (err) {
141
- process.stderr.write('[agent-discover] WS send error: ' +
142
- (err instanceof Error ? err.message : String(err)) +
143
- '\n');
144
- }
28
+ function buildStatePayload(ctx) {
29
+ const servers = ctx.registry.list();
30
+ const serversWithStatus = servers.map((s) => ({
31
+ ...s,
32
+ active: ctx.proxy.isActive(s.name),
33
+ tools: ctx.registry.getTools(s.id),
34
+ }));
35
+ const activeNames = ctx.proxy.getActiveServerNames();
36
+ const active = activeNames.map((name) => ({
37
+ name,
38
+ tools: ctx.proxy.getServerTools(name),
39
+ }));
40
+ return { servers: serversWithStatus, active };
145
41
  }
146
42
  //# sourceMappingURL=ws.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ws.js","sourceRoot":"","sources":["../../src/transport/ws.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ws.js","sourceRoot":"","sources":["../../src/transport/ws.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,uCAAuC;AACvC,EAAE;AACF,6EAA6E;AAC7E,0EAA0E;AAC1E,iEAAiE;AACjE,gFAAgF;AAEhF,OAAO,EAAE,cAAc,IAAI,iBAAiB,EAAiB,MAAM,cAAc,CAAC;AAGlF,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxC,MAAM,UAAU,cAAc,CAAC,UAAkB,EAAE,GAAe;IAChE,OAAO,iBAAiB,CAAC;QACvB,UAAU;QACV,eAAe,EAAE,GAAG,EAAE;YACpB,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,QAAQ,CACzB;;;;;eAKO,CACR,CAAC;YACF,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,MAAM,CAAC;YACvD,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;QACtD,CAAC;QACD,eAAe,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC;QAC7C,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6BAA6B,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAC1F;KACJ,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAe;IACxC,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACpC,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5C,GAAG,CAAC;QACJ,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QAClC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;KACnC,CAAC,CAAC,CAAC;IAEJ,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,IAAI;QACJ,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;KACtC,CAAC,CAAC,CAAC;IAEJ,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-discover",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "mcpName": "io.github.keshrath/agent-discover",
5
5
  "description": "MCP server registry and marketplace — discover, install, activate, and manage MCP tools on demand",
6
6
  "type": "module",
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@modelcontextprotocol/sdk": "^1.12.1",
52
- "agent-common": "^1.0.1",
52
+ "agent-common": "^1.0.3",
53
53
  "better-sqlite3": "12.8.0",
54
54
  "morphdom": "^2.7.8",
55
55
  "ws": "8.20.0"