@dexto/server 1.5.7 → 1.6.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/dist/events/a2a-sse-subscriber.d.ts +1 -1
- package/dist/hono/__tests__/test-fixtures.cjs +27 -6
- package/dist/hono/__tests__/test-fixtures.d.ts +2 -1
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
- package/dist/hono/__tests__/test-fixtures.js +31 -6
- package/dist/hono/index.cjs +17 -2
- package/dist/hono/index.d.ts +897 -76
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +17 -2
- package/dist/hono/routes/a2a-tasks.d.ts +6 -6
- package/dist/hono/routes/agents.cjs +38 -27
- package/dist/hono/routes/agents.d.ts +2 -1
- package/dist/hono/routes/agents.d.ts.map +1 -1
- package/dist/hono/routes/agents.js +37 -31
- package/dist/hono/routes/discovery.cjs +99 -22
- package/dist/hono/routes/discovery.d.ts +14 -12
- package/dist/hono/routes/discovery.d.ts.map +1 -1
- package/dist/hono/routes/discovery.js +89 -22
- package/dist/hono/routes/key.d.ts +4 -4
- package/dist/hono/routes/llm.cjs +21 -7
- package/dist/hono/routes/llm.d.ts +12 -10
- package/dist/hono/routes/llm.d.ts.map +1 -1
- package/dist/hono/routes/llm.js +22 -7
- package/dist/hono/routes/mcp.cjs +96 -14
- package/dist/hono/routes/mcp.d.ts +138 -3
- package/dist/hono/routes/mcp.d.ts.map +1 -1
- package/dist/hono/routes/mcp.js +97 -15
- package/dist/hono/routes/memory.d.ts +4 -4
- package/dist/hono/routes/messages.d.ts +1 -1
- package/dist/hono/routes/models.d.ts +1 -1
- package/dist/hono/routes/queue.cjs +9 -3
- package/dist/hono/routes/queue.d.ts +3 -0
- package/dist/hono/routes/queue.d.ts.map +1 -1
- package/dist/hono/routes/queue.js +9 -3
- package/dist/hono/routes/resources.d.ts +1 -1
- package/dist/hono/routes/schedules.cjs +455 -0
- package/dist/hono/routes/schedules.d.ts +472 -0
- package/dist/hono/routes/schedules.d.ts.map +1 -0
- package/dist/hono/routes/schedules.js +439 -0
- package/dist/hono/routes/search.d.ts +3 -3
- package/dist/hono/routes/sessions.cjs +10 -4
- package/dist/hono/routes/sessions.d.ts +136 -6
- package/dist/hono/routes/sessions.d.ts.map +1 -1
- package/dist/hono/routes/sessions.js +10 -4
- package/dist/hono/routes/tools.cjs +12 -19
- package/dist/hono/routes/tools.d.ts +5 -3
- package/dist/hono/routes/tools.d.ts.map +1 -1
- package/dist/hono/routes/tools.js +12 -19
- package/dist/hono/routes/workspaces.cjs +136 -0
- package/dist/hono/routes/workspaces.d.ts +77 -0
- package/dist/hono/routes/workspaces.d.ts.map +1 -0
- package/dist/hono/routes/workspaces.js +112 -0
- package/dist/hono/schemas/responses.cjs +82 -7
- package/dist/hono/schemas/responses.d.ts +403 -53
- package/dist/hono/schemas/responses.d.ts.map +1 -1
- package/dist/hono/schemas/responses.js +75 -6
- package/dist/hono/start-server.cjs +4 -3
- package/dist/hono/start-server.d.ts +15 -6
- package/dist/hono/start-server.d.ts.map +1 -1
- package/dist/hono/start-server.js +5 -4
- package/dist/index.cjs +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/mcp/mcp-handler.d.ts +2 -2
- package/dist/mcp/mcp-handler.d.ts.map +1 -1
- package/package.json +8 -5
package/dist/hono/routes/mcp.cjs
CHANGED
|
@@ -29,7 +29,11 @@ const McpServerRequestSchema = import_zod_openapi.z.object({
|
|
|
29
29
|
name: import_zod_openapi.z.string().min(1, "Server name is required").describe("A unique name for the server"),
|
|
30
30
|
config: import_core.McpServerConfigSchema.describe("The server configuration object"),
|
|
31
31
|
persistToAgent: import_zod_openapi.z.boolean().optional().describe("If true, saves the server to agent configuration file")
|
|
32
|
-
}).describe("Request body for adding or updating an MCP server");
|
|
32
|
+
}).strict().describe("Request body for adding or updating an MCP server");
|
|
33
|
+
const McpServerUpdateSchema = import_zod_openapi.z.object({
|
|
34
|
+
config: import_core.McpServerConfigSchema.describe("The updated server configuration object"),
|
|
35
|
+
persistToAgent: import_zod_openapi.z.boolean().optional().describe("If true, saves the server to agent configuration file")
|
|
36
|
+
}).strict().describe("Request body for updating an MCP server");
|
|
33
37
|
const ExecuteToolBodySchema = import_zod_openapi.z.record(import_zod_openapi.z.unknown()).describe(
|
|
34
38
|
"Tool execution parameters as JSON object. The specific fields depend on the tool being executed and are defined by the tool's inputSchema."
|
|
35
39
|
);
|
|
@@ -60,7 +64,8 @@ const ToolInfoSchema = import_zod_openapi.z.object({
|
|
|
60
64
|
id: import_zod_openapi.z.string().describe("Tool identifier"),
|
|
61
65
|
name: import_zod_openapi.z.string().describe("Tool name"),
|
|
62
66
|
description: import_zod_openapi.z.string().describe("Tool description"),
|
|
63
|
-
inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters")
|
|
67
|
+
inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters"),
|
|
68
|
+
_meta: import_zod_openapi.z.record(import_zod_openapi.z.unknown()).optional().describe("Optional tool metadata (e.g., MCP Apps UI resource info)")
|
|
64
69
|
}).strict().describe("Tool information");
|
|
65
70
|
const ToolsListResponseSchema = import_zod_openapi.z.object({
|
|
66
71
|
tools: import_zod_openapi.z.array(ToolInfoSchema).describe("Array of available tools")
|
|
@@ -78,6 +83,10 @@ const ToolExecutionResponseSchema = import_zod_openapi.z.object({
|
|
|
78
83
|
data: import_zod_openapi.z.any().optional().describe("Tool execution result data"),
|
|
79
84
|
error: import_zod_openapi.z.string().optional().describe("Error message if execution failed")
|
|
80
85
|
}).strict().describe("Tool execution response");
|
|
86
|
+
const ServerConfigResponseSchema = import_zod_openapi.z.object({
|
|
87
|
+
name: import_zod_openapi.z.string().describe("Server name"),
|
|
88
|
+
config: import_core.McpServerConfigSchema.describe("Server configuration")
|
|
89
|
+
}).strict().describe("MCP server configuration response");
|
|
81
90
|
const ResourcesListResponseSchema = import_zod_openapi.z.object({
|
|
82
91
|
success: import_zod_openapi.z.boolean().describe("Success indicator"),
|
|
83
92
|
resources: import_zod_openapi.z.array(import_responses.ResourceSchema).describe("Array of available resources")
|
|
@@ -89,7 +98,7 @@ const ResourceContentResponseSchema = import_zod_openapi.z.object({
|
|
|
89
98
|
success: import_zod_openapi.z.boolean().describe("Success indicator"),
|
|
90
99
|
data: ResourceContentSchema.describe("Resource content")
|
|
91
100
|
}).strict().describe("Resource content response");
|
|
92
|
-
function createMcpRouter(getAgent) {
|
|
101
|
+
function createMcpRouter(getAgent, getAgentConfigPath) {
|
|
93
102
|
const app = new import_zod_openapi.OpenAPIHono();
|
|
94
103
|
const addServerRoute = (0, import_zod_openapi.createRoute)({
|
|
95
104
|
method: "post",
|
|
@@ -118,6 +127,41 @@ function createMcpRouter(getAgent) {
|
|
|
118
127
|
}
|
|
119
128
|
}
|
|
120
129
|
});
|
|
130
|
+
const getServerConfigRoute = (0, import_zod_openapi.createRoute)({
|
|
131
|
+
method: "get",
|
|
132
|
+
path: "/mcp/servers/{serverId}/config",
|
|
133
|
+
summary: "Get MCP Server Config",
|
|
134
|
+
description: "Retrieves the configuration for a specific MCP server",
|
|
135
|
+
tags: ["mcp"],
|
|
136
|
+
request: {
|
|
137
|
+
params: import_zod_openapi.z.object({ serverId: import_zod_openapi.z.string().describe("The ID of the MCP server") })
|
|
138
|
+
},
|
|
139
|
+
responses: {
|
|
140
|
+
200: {
|
|
141
|
+
description: "Server configuration",
|
|
142
|
+
content: { "application/json": { schema: ServerConfigResponseSchema } }
|
|
143
|
+
},
|
|
144
|
+
404: { description: "Not found" }
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
const updateServerRoute = (0, import_zod_openapi.createRoute)({
|
|
148
|
+
method: "put",
|
|
149
|
+
path: "/mcp/servers/{serverId}",
|
|
150
|
+
summary: "Update MCP Server",
|
|
151
|
+
description: "Updates configuration for an existing MCP server",
|
|
152
|
+
tags: ["mcp"],
|
|
153
|
+
request: {
|
|
154
|
+
params: import_zod_openapi.z.object({ serverId: import_zod_openapi.z.string().describe("The ID of the MCP server") }),
|
|
155
|
+
body: { content: { "application/json": { schema: McpServerUpdateSchema } } }
|
|
156
|
+
},
|
|
157
|
+
responses: {
|
|
158
|
+
200: {
|
|
159
|
+
description: "Server updated",
|
|
160
|
+
content: { "application/json": { schema: ServerStatusResponseSchema } }
|
|
161
|
+
},
|
|
162
|
+
404: { description: "Not found" }
|
|
163
|
+
}
|
|
164
|
+
});
|
|
121
165
|
const toolsRoute = (0, import_zod_openapi.createRoute)({
|
|
122
166
|
method: "get",
|
|
123
167
|
path: "/mcp/servers/{serverId}/tools",
|
|
@@ -237,6 +281,10 @@ function createMcpRouter(getAgent) {
|
|
|
237
281
|
);
|
|
238
282
|
if (persistToAgent === true) {
|
|
239
283
|
try {
|
|
284
|
+
const agentPath = await getAgentConfigPath(ctx);
|
|
285
|
+
if (!agentPath) {
|
|
286
|
+
throw import_core.AgentError.noConfigPath();
|
|
287
|
+
}
|
|
240
288
|
const currentConfig = agent.getEffectiveConfig();
|
|
241
289
|
const updates = {
|
|
242
290
|
mcpServers: {
|
|
@@ -244,16 +292,7 @@ function createMcpRouter(getAgent) {
|
|
|
244
292
|
[name]: config
|
|
245
293
|
}
|
|
246
294
|
};
|
|
247
|
-
|
|
248
|
-
agent.getAgentFilePath(),
|
|
249
|
-
updates
|
|
250
|
-
);
|
|
251
|
-
const reloadResult = await agent.reload(newConfig);
|
|
252
|
-
if (reloadResult.restarted) {
|
|
253
|
-
import_core.logger.info(
|
|
254
|
-
`Agent restarted to apply changes: ${reloadResult.changesApplied.join(", ")}`
|
|
255
|
-
);
|
|
256
|
-
}
|
|
295
|
+
await (0, import_agent_management.updateAgentConfigFile)(agentPath, updates);
|
|
257
296
|
import_core.logger.info(`Saved server '${name}' to agent configuration file`);
|
|
258
297
|
} catch (saveError) {
|
|
259
298
|
const errorMessage = saveError instanceof Error ? saveError.message : String(saveError);
|
|
@@ -279,6 +318,48 @@ function createMcpRouter(getAgent) {
|
|
|
279
318
|
servers.push({ id: name, name, status: "error" });
|
|
280
319
|
}
|
|
281
320
|
return ctx.json({ servers });
|
|
321
|
+
}).openapi(getServerConfigRoute, async (ctx) => {
|
|
322
|
+
const agent = await getAgent(ctx);
|
|
323
|
+
const { serverId } = ctx.req.valid("param");
|
|
324
|
+
const config = agent.getMcpServerConfig(serverId);
|
|
325
|
+
if (!config) {
|
|
326
|
+
return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
|
|
327
|
+
}
|
|
328
|
+
return ctx.json({ name: serverId, config }, 200);
|
|
329
|
+
}).openapi(updateServerRoute, async (ctx) => {
|
|
330
|
+
const agent = await getAgent(ctx);
|
|
331
|
+
const { serverId } = ctx.req.valid("param");
|
|
332
|
+
const { config, persistToAgent } = ctx.req.valid("json");
|
|
333
|
+
const existingConfig = agent.getMcpServerConfig(serverId);
|
|
334
|
+
if (!existingConfig) {
|
|
335
|
+
return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
|
|
336
|
+
}
|
|
337
|
+
await agent.updateMcpServer(serverId, config);
|
|
338
|
+
if (persistToAgent === true) {
|
|
339
|
+
try {
|
|
340
|
+
const agentPath = await getAgentConfigPath(ctx);
|
|
341
|
+
if (!agentPath) {
|
|
342
|
+
throw import_core.AgentError.noConfigPath();
|
|
343
|
+
}
|
|
344
|
+
const currentConfig = agent.getEffectiveConfig();
|
|
345
|
+
const updates = {
|
|
346
|
+
mcpServers: {
|
|
347
|
+
...currentConfig.mcpServers || {},
|
|
348
|
+
[serverId]: config
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
await (0, import_agent_management.updateAgentConfigFile)(agentPath, updates);
|
|
352
|
+
import_core.logger.info(`Saved server '${serverId}' to agent configuration file`);
|
|
353
|
+
} catch (saveError) {
|
|
354
|
+
const errorMessage = saveError instanceof Error ? saveError.message : String(saveError);
|
|
355
|
+
import_core.logger.warn(
|
|
356
|
+
`Failed to persist MCP server '${serverId}' update: ${errorMessage}`,
|
|
357
|
+
{ error: saveError }
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const status = config.enabled === false ? "registered" : "connected";
|
|
362
|
+
return ctx.json({ status, name: serverId }, 200);
|
|
282
363
|
}).openapi(toolsRoute, async (ctx) => {
|
|
283
364
|
const agent = await getAgent(ctx);
|
|
284
365
|
const { serverId } = ctx.req.valid("param");
|
|
@@ -291,7 +372,8 @@ function createMcpRouter(getAgent) {
|
|
|
291
372
|
id: toolName,
|
|
292
373
|
name: toolName,
|
|
293
374
|
description: toolDef.description || "",
|
|
294
|
-
inputSchema: toolDef.parameters
|
|
375
|
+
inputSchema: toolDef.parameters,
|
|
376
|
+
_meta: toolDef._meta
|
|
295
377
|
}));
|
|
296
378
|
return ctx.json({ tools });
|
|
297
379
|
}).openapi(deleteServerRoute, async (ctx) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OpenAPIHono } from '@hono/zod-openapi';
|
|
2
|
-
import type { GetAgentFn } from '../index.js';
|
|
3
|
-
export declare function createMcpRouter(getAgent: GetAgentFn): OpenAPIHono<import("hono").Env, {
|
|
2
|
+
import type { GetAgentConfigPathFn, GetAgentFn } from '../index.js';
|
|
3
|
+
export declare function createMcpRouter(getAgent: GetAgentFn, getAgentConfigPath: GetAgentConfigPathFn): OpenAPIHono<import("hono").Env, {
|
|
4
4
|
"/mcp/servers": {
|
|
5
5
|
$post: {
|
|
6
6
|
input: {
|
|
@@ -55,6 +55,138 @@ export declare function createMcpRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
55
55
|
status: 200;
|
|
56
56
|
};
|
|
57
57
|
};
|
|
58
|
+
} & {
|
|
59
|
+
"/mcp/servers/:serverId/config": {
|
|
60
|
+
$get: {
|
|
61
|
+
input: {
|
|
62
|
+
param: {
|
|
63
|
+
serverId: string;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
output: {};
|
|
67
|
+
outputFormat: string;
|
|
68
|
+
status: 404;
|
|
69
|
+
} | {
|
|
70
|
+
input: {
|
|
71
|
+
param: {
|
|
72
|
+
serverId: string;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
output: {
|
|
76
|
+
config: {
|
|
77
|
+
timeout: number;
|
|
78
|
+
type: "stdio";
|
|
79
|
+
enabled: boolean;
|
|
80
|
+
command: string;
|
|
81
|
+
args: string[];
|
|
82
|
+
env: {
|
|
83
|
+
[x: string]: string;
|
|
84
|
+
};
|
|
85
|
+
connectionMode: "strict" | "lenient";
|
|
86
|
+
} | {
|
|
87
|
+
timeout: number;
|
|
88
|
+
type: "sse";
|
|
89
|
+
enabled: boolean;
|
|
90
|
+
connectionMode: "strict" | "lenient";
|
|
91
|
+
url: string;
|
|
92
|
+
headers: {
|
|
93
|
+
[x: string]: string;
|
|
94
|
+
};
|
|
95
|
+
} | {
|
|
96
|
+
timeout: number;
|
|
97
|
+
type: "http";
|
|
98
|
+
enabled: boolean;
|
|
99
|
+
connectionMode: "strict" | "lenient";
|
|
100
|
+
url: string;
|
|
101
|
+
headers: {
|
|
102
|
+
[x: string]: string;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
name: string;
|
|
106
|
+
};
|
|
107
|
+
outputFormat: "json";
|
|
108
|
+
status: 200;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
} & {
|
|
112
|
+
"/mcp/servers/:serverId": {
|
|
113
|
+
$put: {
|
|
114
|
+
input: {
|
|
115
|
+
param: {
|
|
116
|
+
serverId: string;
|
|
117
|
+
};
|
|
118
|
+
} & {
|
|
119
|
+
json: {
|
|
120
|
+
config: {
|
|
121
|
+
type: "stdio";
|
|
122
|
+
command: string;
|
|
123
|
+
timeout?: number | undefined;
|
|
124
|
+
enabled?: boolean | undefined;
|
|
125
|
+
args?: string[] | undefined;
|
|
126
|
+
env?: Record<string, string> | undefined;
|
|
127
|
+
connectionMode?: "strict" | "lenient" | undefined;
|
|
128
|
+
} | {
|
|
129
|
+
type: "sse";
|
|
130
|
+
url: string;
|
|
131
|
+
timeout?: number | undefined;
|
|
132
|
+
enabled?: boolean | undefined;
|
|
133
|
+
connectionMode?: "strict" | "lenient" | undefined;
|
|
134
|
+
headers?: Record<string, string> | undefined;
|
|
135
|
+
} | {
|
|
136
|
+
type: "http";
|
|
137
|
+
url: string;
|
|
138
|
+
timeout?: number | undefined;
|
|
139
|
+
enabled?: boolean | undefined;
|
|
140
|
+
connectionMode?: "strict" | "lenient" | undefined;
|
|
141
|
+
headers?: Record<string, string> | undefined;
|
|
142
|
+
};
|
|
143
|
+
persistToAgent?: boolean | undefined;
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
output: {};
|
|
147
|
+
outputFormat: string;
|
|
148
|
+
status: 404;
|
|
149
|
+
} | {
|
|
150
|
+
input: {
|
|
151
|
+
param: {
|
|
152
|
+
serverId: string;
|
|
153
|
+
};
|
|
154
|
+
} & {
|
|
155
|
+
json: {
|
|
156
|
+
config: {
|
|
157
|
+
type: "stdio";
|
|
158
|
+
command: string;
|
|
159
|
+
timeout?: number | undefined;
|
|
160
|
+
enabled?: boolean | undefined;
|
|
161
|
+
args?: string[] | undefined;
|
|
162
|
+
env?: Record<string, string> | undefined;
|
|
163
|
+
connectionMode?: "strict" | "lenient" | undefined;
|
|
164
|
+
} | {
|
|
165
|
+
type: "sse";
|
|
166
|
+
url: string;
|
|
167
|
+
timeout?: number | undefined;
|
|
168
|
+
enabled?: boolean | undefined;
|
|
169
|
+
connectionMode?: "strict" | "lenient" | undefined;
|
|
170
|
+
headers?: Record<string, string> | undefined;
|
|
171
|
+
} | {
|
|
172
|
+
type: "http";
|
|
173
|
+
url: string;
|
|
174
|
+
timeout?: number | undefined;
|
|
175
|
+
enabled?: boolean | undefined;
|
|
176
|
+
connectionMode?: "strict" | "lenient" | undefined;
|
|
177
|
+
headers?: Record<string, string> | undefined;
|
|
178
|
+
};
|
|
179
|
+
persistToAgent?: boolean | undefined;
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
output: {
|
|
183
|
+
status: string;
|
|
184
|
+
name: string;
|
|
185
|
+
};
|
|
186
|
+
outputFormat: "json";
|
|
187
|
+
status: 200;
|
|
188
|
+
};
|
|
189
|
+
};
|
|
58
190
|
} & {
|
|
59
191
|
"/mcp/servers/:serverId/tools": {
|
|
60
192
|
$get: {
|
|
@@ -91,6 +223,9 @@ export declare function createMcpRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
91
223
|
} | undefined;
|
|
92
224
|
required?: string[] | undefined;
|
|
93
225
|
} | undefined;
|
|
226
|
+
_meta?: {
|
|
227
|
+
[x: string]: import("hono/utils/types").JSONValue;
|
|
228
|
+
} | undefined;
|
|
94
229
|
}[];
|
|
95
230
|
};
|
|
96
231
|
outputFormat: "json";
|
|
@@ -197,7 +332,6 @@ export declare function createMcpRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
197
332
|
};
|
|
198
333
|
};
|
|
199
334
|
output: {
|
|
200
|
-
success: boolean;
|
|
201
335
|
resources: {
|
|
202
336
|
uri: string;
|
|
203
337
|
source: "mcp" | "internal";
|
|
@@ -211,6 +345,7 @@ export declare function createMcpRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
211
345
|
size?: number | undefined;
|
|
212
346
|
lastModified?: string | undefined;
|
|
213
347
|
}[];
|
|
348
|
+
success: boolean;
|
|
214
349
|
};
|
|
215
350
|
outputFormat: "json";
|
|
216
351
|
status: 200;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAIhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAIhE,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+JpE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,kBAAkB,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAuY7F"}
|
package/dist/hono/routes/mcp.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
|
-
import { logger, McpServerConfigSchema, MCP_CONNECTION_STATUSES } from "@dexto/core";
|
|
2
|
+
import { AgentError, logger, McpServerConfigSchema, MCP_CONNECTION_STATUSES } from "@dexto/core";
|
|
3
3
|
import { updateAgentConfigFile } from "@dexto/agent-management";
|
|
4
4
|
import { ResourceSchema } from "../schemas/responses.js";
|
|
5
5
|
const McpServerRequestSchema = z.object({
|
|
6
6
|
name: z.string().min(1, "Server name is required").describe("A unique name for the server"),
|
|
7
7
|
config: McpServerConfigSchema.describe("The server configuration object"),
|
|
8
8
|
persistToAgent: z.boolean().optional().describe("If true, saves the server to agent configuration file")
|
|
9
|
-
}).describe("Request body for adding or updating an MCP server");
|
|
9
|
+
}).strict().describe("Request body for adding or updating an MCP server");
|
|
10
|
+
const McpServerUpdateSchema = z.object({
|
|
11
|
+
config: McpServerConfigSchema.describe("The updated server configuration object"),
|
|
12
|
+
persistToAgent: z.boolean().optional().describe("If true, saves the server to agent configuration file")
|
|
13
|
+
}).strict().describe("Request body for updating an MCP server");
|
|
10
14
|
const ExecuteToolBodySchema = z.record(z.unknown()).describe(
|
|
11
15
|
"Tool execution parameters as JSON object. The specific fields depend on the tool being executed and are defined by the tool's inputSchema."
|
|
12
16
|
);
|
|
@@ -37,7 +41,8 @@ const ToolInfoSchema = z.object({
|
|
|
37
41
|
id: z.string().describe("Tool identifier"),
|
|
38
42
|
name: z.string().describe("Tool name"),
|
|
39
43
|
description: z.string().describe("Tool description"),
|
|
40
|
-
inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters")
|
|
44
|
+
inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters"),
|
|
45
|
+
_meta: z.record(z.unknown()).optional().describe("Optional tool metadata (e.g., MCP Apps UI resource info)")
|
|
41
46
|
}).strict().describe("Tool information");
|
|
42
47
|
const ToolsListResponseSchema = z.object({
|
|
43
48
|
tools: z.array(ToolInfoSchema).describe("Array of available tools")
|
|
@@ -55,6 +60,10 @@ const ToolExecutionResponseSchema = z.object({
|
|
|
55
60
|
data: z.any().optional().describe("Tool execution result data"),
|
|
56
61
|
error: z.string().optional().describe("Error message if execution failed")
|
|
57
62
|
}).strict().describe("Tool execution response");
|
|
63
|
+
const ServerConfigResponseSchema = z.object({
|
|
64
|
+
name: z.string().describe("Server name"),
|
|
65
|
+
config: McpServerConfigSchema.describe("Server configuration")
|
|
66
|
+
}).strict().describe("MCP server configuration response");
|
|
58
67
|
const ResourcesListResponseSchema = z.object({
|
|
59
68
|
success: z.boolean().describe("Success indicator"),
|
|
60
69
|
resources: z.array(ResourceSchema).describe("Array of available resources")
|
|
@@ -66,7 +75,7 @@ const ResourceContentResponseSchema = z.object({
|
|
|
66
75
|
success: z.boolean().describe("Success indicator"),
|
|
67
76
|
data: ResourceContentSchema.describe("Resource content")
|
|
68
77
|
}).strict().describe("Resource content response");
|
|
69
|
-
function createMcpRouter(getAgent) {
|
|
78
|
+
function createMcpRouter(getAgent, getAgentConfigPath) {
|
|
70
79
|
const app = new OpenAPIHono();
|
|
71
80
|
const addServerRoute = createRoute({
|
|
72
81
|
method: "post",
|
|
@@ -95,6 +104,41 @@ function createMcpRouter(getAgent) {
|
|
|
95
104
|
}
|
|
96
105
|
}
|
|
97
106
|
});
|
|
107
|
+
const getServerConfigRoute = createRoute({
|
|
108
|
+
method: "get",
|
|
109
|
+
path: "/mcp/servers/{serverId}/config",
|
|
110
|
+
summary: "Get MCP Server Config",
|
|
111
|
+
description: "Retrieves the configuration for a specific MCP server",
|
|
112
|
+
tags: ["mcp"],
|
|
113
|
+
request: {
|
|
114
|
+
params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
|
|
115
|
+
},
|
|
116
|
+
responses: {
|
|
117
|
+
200: {
|
|
118
|
+
description: "Server configuration",
|
|
119
|
+
content: { "application/json": { schema: ServerConfigResponseSchema } }
|
|
120
|
+
},
|
|
121
|
+
404: { description: "Not found" }
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
const updateServerRoute = createRoute({
|
|
125
|
+
method: "put",
|
|
126
|
+
path: "/mcp/servers/{serverId}",
|
|
127
|
+
summary: "Update MCP Server",
|
|
128
|
+
description: "Updates configuration for an existing MCP server",
|
|
129
|
+
tags: ["mcp"],
|
|
130
|
+
request: {
|
|
131
|
+
params: z.object({ serverId: z.string().describe("The ID of the MCP server") }),
|
|
132
|
+
body: { content: { "application/json": { schema: McpServerUpdateSchema } } }
|
|
133
|
+
},
|
|
134
|
+
responses: {
|
|
135
|
+
200: {
|
|
136
|
+
description: "Server updated",
|
|
137
|
+
content: { "application/json": { schema: ServerStatusResponseSchema } }
|
|
138
|
+
},
|
|
139
|
+
404: { description: "Not found" }
|
|
140
|
+
}
|
|
141
|
+
});
|
|
98
142
|
const toolsRoute = createRoute({
|
|
99
143
|
method: "get",
|
|
100
144
|
path: "/mcp/servers/{serverId}/tools",
|
|
@@ -214,6 +258,10 @@ function createMcpRouter(getAgent) {
|
|
|
214
258
|
);
|
|
215
259
|
if (persistToAgent === true) {
|
|
216
260
|
try {
|
|
261
|
+
const agentPath = await getAgentConfigPath(ctx);
|
|
262
|
+
if (!agentPath) {
|
|
263
|
+
throw AgentError.noConfigPath();
|
|
264
|
+
}
|
|
217
265
|
const currentConfig = agent.getEffectiveConfig();
|
|
218
266
|
const updates = {
|
|
219
267
|
mcpServers: {
|
|
@@ -221,16 +269,7 @@ function createMcpRouter(getAgent) {
|
|
|
221
269
|
[name]: config
|
|
222
270
|
}
|
|
223
271
|
};
|
|
224
|
-
|
|
225
|
-
agent.getAgentFilePath(),
|
|
226
|
-
updates
|
|
227
|
-
);
|
|
228
|
-
const reloadResult = await agent.reload(newConfig);
|
|
229
|
-
if (reloadResult.restarted) {
|
|
230
|
-
logger.info(
|
|
231
|
-
`Agent restarted to apply changes: ${reloadResult.changesApplied.join(", ")}`
|
|
232
|
-
);
|
|
233
|
-
}
|
|
272
|
+
await updateAgentConfigFile(agentPath, updates);
|
|
234
273
|
logger.info(`Saved server '${name}' to agent configuration file`);
|
|
235
274
|
} catch (saveError) {
|
|
236
275
|
const errorMessage = saveError instanceof Error ? saveError.message : String(saveError);
|
|
@@ -256,6 +295,48 @@ function createMcpRouter(getAgent) {
|
|
|
256
295
|
servers.push({ id: name, name, status: "error" });
|
|
257
296
|
}
|
|
258
297
|
return ctx.json({ servers });
|
|
298
|
+
}).openapi(getServerConfigRoute, async (ctx) => {
|
|
299
|
+
const agent = await getAgent(ctx);
|
|
300
|
+
const { serverId } = ctx.req.valid("param");
|
|
301
|
+
const config = agent.getMcpServerConfig(serverId);
|
|
302
|
+
if (!config) {
|
|
303
|
+
return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
|
|
304
|
+
}
|
|
305
|
+
return ctx.json({ name: serverId, config }, 200);
|
|
306
|
+
}).openapi(updateServerRoute, async (ctx) => {
|
|
307
|
+
const agent = await getAgent(ctx);
|
|
308
|
+
const { serverId } = ctx.req.valid("param");
|
|
309
|
+
const { config, persistToAgent } = ctx.req.valid("json");
|
|
310
|
+
const existingConfig = agent.getMcpServerConfig(serverId);
|
|
311
|
+
if (!existingConfig) {
|
|
312
|
+
return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
|
|
313
|
+
}
|
|
314
|
+
await agent.updateMcpServer(serverId, config);
|
|
315
|
+
if (persistToAgent === true) {
|
|
316
|
+
try {
|
|
317
|
+
const agentPath = await getAgentConfigPath(ctx);
|
|
318
|
+
if (!agentPath) {
|
|
319
|
+
throw AgentError.noConfigPath();
|
|
320
|
+
}
|
|
321
|
+
const currentConfig = agent.getEffectiveConfig();
|
|
322
|
+
const updates = {
|
|
323
|
+
mcpServers: {
|
|
324
|
+
...currentConfig.mcpServers || {},
|
|
325
|
+
[serverId]: config
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
await updateAgentConfigFile(agentPath, updates);
|
|
329
|
+
logger.info(`Saved server '${serverId}' to agent configuration file`);
|
|
330
|
+
} catch (saveError) {
|
|
331
|
+
const errorMessage = saveError instanceof Error ? saveError.message : String(saveError);
|
|
332
|
+
logger.warn(
|
|
333
|
+
`Failed to persist MCP server '${serverId}' update: ${errorMessage}`,
|
|
334
|
+
{ error: saveError }
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
const status = config.enabled === false ? "registered" : "connected";
|
|
339
|
+
return ctx.json({ status, name: serverId }, 200);
|
|
259
340
|
}).openapi(toolsRoute, async (ctx) => {
|
|
260
341
|
const agent = await getAgent(ctx);
|
|
261
342
|
const { serverId } = ctx.req.valid("param");
|
|
@@ -268,7 +349,8 @@ function createMcpRouter(getAgent) {
|
|
|
268
349
|
id: toolName,
|
|
269
350
|
name: toolName,
|
|
270
351
|
description: toolDef.description || "",
|
|
271
|
-
inputSchema: toolDef.parameters
|
|
352
|
+
inputSchema: toolDef.parameters,
|
|
353
|
+
_meta: toolDef._meta
|
|
272
354
|
}));
|
|
273
355
|
return ctx.json({ tools });
|
|
274
356
|
}).openapi(deleteServerRoute, async (ctx) => {
|
|
@@ -19,8 +19,8 @@ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<im
|
|
|
19
19
|
ok: true;
|
|
20
20
|
memory: {
|
|
21
21
|
content: string;
|
|
22
|
-
createdAt: number;
|
|
23
22
|
id: string;
|
|
23
|
+
createdAt: number;
|
|
24
24
|
updatedAt: number;
|
|
25
25
|
metadata?: {
|
|
26
26
|
[x: string]: import("hono/utils/types").JSONValue;
|
|
@@ -49,8 +49,8 @@ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<im
|
|
|
49
49
|
output: {
|
|
50
50
|
memories: {
|
|
51
51
|
content: string;
|
|
52
|
-
createdAt: number;
|
|
53
52
|
id: string;
|
|
53
|
+
createdAt: number;
|
|
54
54
|
updatedAt: number;
|
|
55
55
|
metadata?: {
|
|
56
56
|
[x: string]: import("hono/utils/types").JSONValue;
|
|
@@ -77,8 +77,8 @@ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<im
|
|
|
77
77
|
ok: true;
|
|
78
78
|
memory: {
|
|
79
79
|
content: string;
|
|
80
|
-
createdAt: number;
|
|
81
80
|
id: string;
|
|
81
|
+
createdAt: number;
|
|
82
82
|
updatedAt: number;
|
|
83
83
|
metadata?: {
|
|
84
84
|
[x: string]: import("hono/utils/types").JSONValue;
|
|
@@ -113,8 +113,8 @@ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<im
|
|
|
113
113
|
ok: true;
|
|
114
114
|
memory: {
|
|
115
115
|
content: string;
|
|
116
|
-
createdAt: number;
|
|
117
116
|
id: string;
|
|
117
|
+
createdAt: number;
|
|
118
118
|
updatedAt: number;
|
|
119
119
|
metadata?: {
|
|
120
120
|
[x: string]: import("hono/utils/types").JSONValue;
|
|
@@ -106,7 +106,7 @@ export declare function createMessagesRouter(getAgent: GetAgentFn, approvalCoord
|
|
|
106
106
|
totalTokens?: number | undefined;
|
|
107
107
|
} | undefined;
|
|
108
108
|
model?: string | undefined;
|
|
109
|
-
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto" | undefined;
|
|
109
|
+
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova" | undefined;
|
|
110
110
|
};
|
|
111
111
|
outputFormat: "json";
|
|
112
112
|
status: 200;
|
|
@@ -15,7 +15,7 @@ export declare function createModelsRouter(): OpenAPIHono<import("hono").Env, {
|
|
|
15
15
|
displayName: string;
|
|
16
16
|
filePath: string;
|
|
17
17
|
sizeBytes: number;
|
|
18
|
-
source?: "
|
|
18
|
+
source?: "huggingface" | "manual" | undefined;
|
|
19
19
|
contextLength?: number | undefined;
|
|
20
20
|
}[];
|
|
21
21
|
};
|
|
@@ -27,7 +27,8 @@ const QueuedMessageSchema = import_zod_openapi.z.object({
|
|
|
27
27
|
id: import_zod_openapi.z.string().describe("Unique identifier for the queued message"),
|
|
28
28
|
content: import_zod_openapi.z.array(import_responses.ContentPartSchema).describe("Message content parts"),
|
|
29
29
|
queuedAt: import_zod_openapi.z.number().describe("Unix timestamp when message was queued"),
|
|
30
|
-
metadata: import_zod_openapi.z.record(import_zod_openapi.z.unknown()).optional().describe("Optional metadata")
|
|
30
|
+
metadata: import_zod_openapi.z.record(import_zod_openapi.z.unknown()).optional().describe("Optional metadata"),
|
|
31
|
+
kind: import_zod_openapi.z.enum(["default", "background"]).optional().describe("Optional queued message kind")
|
|
31
32
|
}).strict().describe("A message waiting in the queue");
|
|
32
33
|
const TextPartSchema = import_zod_openapi.z.object({
|
|
33
34
|
type: import_zod_openapi.z.literal("text").describe("Content type identifier"),
|
|
@@ -46,7 +47,8 @@ const FilePartSchema = import_zod_openapi.z.object({
|
|
|
46
47
|
}).describe("File content part");
|
|
47
48
|
const QueueContentPartSchema = import_zod_openapi.z.discriminatedUnion("type", [TextPartSchema, ImagePartSchema, FilePartSchema]).describe("Content part - text, image, or file");
|
|
48
49
|
const QueueMessageBodySchema = import_zod_openapi.z.object({
|
|
49
|
-
content: import_zod_openapi.z.union([import_zod_openapi.z.string(), import_zod_openapi.z.array(QueueContentPartSchema)]).describe("Message content - string for text, or ContentPart[] for multimodal")
|
|
50
|
+
content: import_zod_openapi.z.union([import_zod_openapi.z.string(), import_zod_openapi.z.array(QueueContentPartSchema)]).describe("Message content - string for text, or ContentPart[] for multimodal"),
|
|
51
|
+
kind: import_zod_openapi.z.enum(["default", "background"]).optional().describe("Optional queued message kind")
|
|
50
52
|
}).describe("Request body for queueing a message");
|
|
51
53
|
function createQueueRouter(getAgent) {
|
|
52
54
|
const app = new import_zod_openapi.OpenAPIHono();
|
|
@@ -172,7 +174,11 @@ function createQueueRouter(getAgent) {
|
|
|
172
174
|
const { sessionId } = ctx.req.valid("param");
|
|
173
175
|
const { content: rawContent } = ctx.req.valid("json");
|
|
174
176
|
const content = typeof rawContent === "string" ? [{ type: "text", text: rawContent }] : rawContent;
|
|
175
|
-
const
|
|
177
|
+
const { kind } = ctx.req.valid("json");
|
|
178
|
+
const result = await agent.queueMessage(sessionId, {
|
|
179
|
+
content,
|
|
180
|
+
...kind !== void 0 && { kind }
|
|
181
|
+
});
|
|
176
182
|
return ctx.json(
|
|
177
183
|
{
|
|
178
184
|
queued: result.queued,
|
|
@@ -52,6 +52,7 @@ export declare function createQueueRouter(getAgent: GetAgentFn): OpenAPIHono<imp
|
|
|
52
52
|
metadata?: {
|
|
53
53
|
[x: string]: import("hono/utils/types").JSONValue;
|
|
54
54
|
} | undefined;
|
|
55
|
+
kind?: "default" | "background" | undefined;
|
|
55
56
|
}[];
|
|
56
57
|
count: number;
|
|
57
58
|
};
|
|
@@ -81,6 +82,7 @@ export declare function createQueueRouter(getAgent: GetAgentFn): OpenAPIHono<imp
|
|
|
81
82
|
data: string;
|
|
82
83
|
filename?: string | undefined;
|
|
83
84
|
})[];
|
|
85
|
+
kind?: "default" | "background" | undefined;
|
|
84
86
|
};
|
|
85
87
|
};
|
|
86
88
|
output: {};
|
|
@@ -106,6 +108,7 @@ export declare function createQueueRouter(getAgent: GetAgentFn): OpenAPIHono<imp
|
|
|
106
108
|
data: string;
|
|
107
109
|
filename?: string | undefined;
|
|
108
110
|
})[];
|
|
111
|
+
kind?: "default" | "background" | undefined;
|
|
109
112
|
};
|
|
110
113
|
};
|
|
111
114
|
output: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,aAAa,CAAC;AAE3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,aAAa,CAAC;AAE3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAuDrE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwLrD"}
|