@dexto/server 1.6.19 → 1.6.21
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/a2a/jsonrpc/methods.cjs +1 -1
- package/dist/a2a/jsonrpc/methods.d.ts +14 -4
- package/dist/a2a/jsonrpc/methods.d.ts.map +1 -1
- package/dist/a2a/jsonrpc/methods.js +1 -1
- package/dist/hono/index.cjs +39 -8
- package/dist/hono/index.d.ts +43 -4503
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +42 -9
- package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -1
- package/dist/hono/routes/a2a-tasks.cjs +173 -34
- package/dist/hono/routes/a2a-tasks.d.ts +1 -498
- package/dist/hono/routes/a2a-tasks.d.ts.map +1 -1
- package/dist/hono/routes/a2a-tasks.js +177 -34
- package/dist/hono/routes/a2a.d.ts.map +1 -1
- package/dist/hono/routes/agents.cjs +410 -329
- package/dist/hono/routes/agents.d.ts +16048 -73
- package/dist/hono/routes/agents.d.ts.map +1 -1
- package/dist/hono/routes/agents.js +418 -330
- package/dist/hono/routes/approvals.cjs +103 -78
- package/dist/hono/routes/approvals.d.ts +2090 -112
- package/dist/hono/routes/approvals.d.ts.map +1 -1
- package/dist/hono/routes/approvals.js +108 -78
- package/dist/hono/routes/dexto-auth.cjs +40 -33
- package/dist/hono/routes/dexto-auth.d.ts +401 -2
- package/dist/hono/routes/dexto-auth.d.ts.map +1 -1
- package/dist/hono/routes/dexto-auth.js +40 -33
- package/dist/hono/routes/discovery.cjs +16 -14
- package/dist/hono/routes/discovery.d.ts +586 -1
- package/dist/hono/routes/discovery.d.ts.map +1 -1
- package/dist/hono/routes/discovery.js +16 -14
- package/dist/hono/routes/greeting.cjs +26 -22
- package/dist/hono/routes/greeting.d.ts +787 -3
- package/dist/hono/routes/greeting.d.ts.map +1 -1
- package/dist/hono/routes/greeting.js +26 -22
- package/dist/hono/routes/health.d.ts +1 -1
- package/dist/hono/routes/key.cjs +60 -52
- package/dist/hono/routes/key.d.ts +1597 -1
- package/dist/hono/routes/key.d.ts.map +1 -1
- package/dist/hono/routes/key.js +60 -52
- package/dist/hono/routes/llm.cjs +381 -348
- package/dist/hono/routes/llm.d.ts +12137 -87
- package/dist/hono/routes/llm.d.ts.map +1 -1
- package/dist/hono/routes/llm.js +385 -348
- package/dist/hono/routes/mcp.cjs +273 -212
- package/dist/hono/routes/mcp.d.ts +6605 -316
- package/dist/hono/routes/mcp.d.ts.map +1 -1
- package/dist/hono/routes/mcp.js +287 -213
- package/dist/hono/routes/memory.cjs +102 -89
- package/dist/hono/routes/memory.d.ts +5368 -4
- package/dist/hono/routes/memory.d.ts.map +1 -1
- package/dist/hono/routes/memory.js +108 -90
- package/dist/hono/routes/messages.cjs +171 -164
- package/dist/hono/routes/messages.d.ts +3899 -10
- package/dist/hono/routes/messages.d.ts.map +1 -1
- package/dist/hono/routes/messages.js +181 -165
- package/dist/hono/routes/models.cjs +106 -64
- package/dist/hono/routes/models.d.ts +2874 -1
- package/dist/hono/routes/models.d.ts.map +1 -1
- package/dist/hono/routes/models.js +108 -64
- package/dist/hono/routes/openrouter.cjs +79 -65
- package/dist/hono/routes/openrouter.d.ts +854 -1
- package/dist/hono/routes/openrouter.d.ts.map +1 -1
- package/dist/hono/routes/openrouter.js +79 -65
- package/dist/hono/routes/prompts.cjs +137 -104
- package/dist/hono/routes/prompts.d.ts +2820 -12
- package/dist/hono/routes/prompts.d.ts.map +1 -1
- package/dist/hono/routes/prompts.js +144 -105
- package/dist/hono/routes/queue.cjs +158 -132
- package/dist/hono/routes/queue.d.ts +5148 -13
- package/dist/hono/routes/queue.d.ts.map +1 -1
- package/dist/hono/routes/queue.js +168 -133
- package/dist/hono/routes/resources.cjs +65 -46
- package/dist/hono/routes/resources.d.ts +1983 -5
- package/dist/hono/routes/resources.d.ts.map +1 -1
- package/dist/hono/routes/resources.js +72 -47
- package/dist/hono/routes/schedules.cjs +233 -226
- package/dist/hono/routes/schedules.d.ts +4202 -26
- package/dist/hono/routes/schedules.d.ts.map +1 -1
- package/dist/hono/routes/schedules.js +233 -226
- package/dist/hono/routes/search.cjs +34 -30
- package/dist/hono/routes/search.d.ts +2837 -14
- package/dist/hono/routes/search.d.ts.map +1 -1
- package/dist/hono/routes/search.js +40 -31
- package/dist/hono/routes/sessions.cjs +404 -392
- package/dist/hono/routes/sessions.d.ts +16585 -30
- package/dist/hono/routes/sessions.d.ts.map +1 -1
- package/dist/hono/routes/sessions.js +408 -393
- package/dist/hono/routes/static.d.ts.map +1 -1
- package/dist/hono/routes/system-prompt.cjs +57 -61
- package/dist/hono/routes/system-prompt.d.ts +1228 -2
- package/dist/hono/routes/system-prompt.d.ts.map +1 -1
- package/dist/hono/routes/system-prompt.js +58 -62
- package/dist/hono/routes/tools.cjs +29 -34
- package/dist/hono/routes/tools.d.ts +1756 -7
- package/dist/hono/routes/tools.d.ts.map +1 -1
- package/dist/hono/routes/tools.js +33 -33
- package/dist/hono/routes/webhooks.cjs +159 -132
- package/dist/hono/routes/webhooks.d.ts +2504 -14
- package/dist/hono/routes/webhooks.d.ts.map +1 -1
- package/dist/hono/routes/webhooks.js +163 -132
- package/dist/hono/routes/workspaces.cjs +84 -79
- package/dist/hono/routes/workspaces.d.ts +2093 -2
- package/dist/hono/routes/workspaces.d.ts.map +1 -1
- package/dist/hono/routes/workspaces.js +89 -80
- package/dist/hono/schemas/responses.cjs +492 -235
- package/dist/hono/schemas/responses.d.ts +1461 -146
- package/dist/hono/schemas/responses.d.ts.map +1 -1
- package/dist/hono/schemas/responses.js +247 -9
- package/dist/hono/types.d.ts +11 -0
- package/dist/hono/types.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/hono/routes/mcp.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AgentError,
|
|
4
|
+
logger,
|
|
5
|
+
MCPError,
|
|
6
|
+
McpServerConfigSchema,
|
|
7
|
+
MCP_CONNECTION_STATUSES
|
|
8
|
+
} from "@dexto/core";
|
|
3
9
|
import { updateAgentConfigFile } from "@dexto/agent-management";
|
|
4
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
ApiErrorResponseSchema,
|
|
12
|
+
BadRequestErrorResponse,
|
|
13
|
+
InternalErrorResponse,
|
|
14
|
+
JsonObjectSchema,
|
|
15
|
+
JsonValueSchema,
|
|
16
|
+
ToolInputSchema
|
|
17
|
+
} from "../schemas/responses.js";
|
|
5
18
|
const McpServerRequestSchema = z.object({
|
|
6
19
|
name: z.string().min(1, "Server name is required").describe("A unique name for the server"),
|
|
7
20
|
config: McpServerConfigSchema.describe("The server configuration object"),
|
|
@@ -11,7 +24,7 @@ const McpServerUpdateSchema = z.object({
|
|
|
11
24
|
config: McpServerConfigSchema.describe("The updated server configuration object"),
|
|
12
25
|
persistToAgent: z.boolean().optional().describe("If true, saves the server to agent configuration file")
|
|
13
26
|
}).strict().describe("Request body for updating an MCP server");
|
|
14
|
-
const ExecuteToolBodySchema =
|
|
27
|
+
const ExecuteToolBodySchema = JsonObjectSchema.describe(
|
|
15
28
|
"Tool execution parameters as JSON object. The specific fields depend on the tool being executed and are defined by the tool's inputSchema."
|
|
16
29
|
);
|
|
17
30
|
const ServerStatusResponseSchema = z.object({
|
|
@@ -26,23 +39,14 @@ const ServerInfoSchema = z.object({
|
|
|
26
39
|
const ServersListResponseSchema = z.object({
|
|
27
40
|
servers: z.array(ServerInfoSchema).describe("Array of server information")
|
|
28
41
|
}).strict().describe("List of MCP servers");
|
|
29
|
-
const JsonSchemaProperty = z.object({
|
|
30
|
-
type: z.enum(["string", "number", "integer", "boolean", "object", "array"]).optional().describe("Property type"),
|
|
31
|
-
description: z.string().optional().describe("Property description"),
|
|
32
|
-
enum: z.array(z.union([z.string(), z.number(), z.boolean()])).optional().describe("Enum values"),
|
|
33
|
-
default: z.any().optional().describe("Default value")
|
|
34
|
-
}).passthrough().describe("JSON Schema property definition");
|
|
35
|
-
const ToolInputSchema = z.object({
|
|
36
|
-
type: z.literal("object").optional().describe('Schema type, always "object" when present'),
|
|
37
|
-
properties: z.record(JsonSchemaProperty).optional().describe("Property definitions"),
|
|
38
|
-
required: z.array(z.string()).optional().describe("Required property names")
|
|
39
|
-
}).passthrough().describe("JSON Schema for tool input parameters");
|
|
40
42
|
const ToolInfoSchema = z.object({
|
|
41
43
|
id: z.string().describe("Tool identifier"),
|
|
42
44
|
name: z.string().describe("Tool name"),
|
|
43
45
|
description: z.string().describe("Tool description"),
|
|
44
46
|
inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters"),
|
|
45
|
-
_meta:
|
|
47
|
+
_meta: JsonObjectSchema.optional().describe(
|
|
48
|
+
"Optional tool metadata (e.g., MCP Apps UI resource info)"
|
|
49
|
+
)
|
|
46
50
|
}).strict().describe("Tool information");
|
|
47
51
|
const ToolsListResponseSchema = z.object({
|
|
48
52
|
tools: z.array(ToolInfoSchema).describe("Array of available tools")
|
|
@@ -57,198 +61,234 @@ const RestartResponseSchema = z.object({
|
|
|
57
61
|
}).strict().describe("Server restart response");
|
|
58
62
|
const ToolExecutionResponseSchema = z.object({
|
|
59
63
|
success: z.boolean().describe("Whether tool execution succeeded"),
|
|
60
|
-
data:
|
|
64
|
+
data: JsonValueSchema.optional().describe("Tool execution result data"),
|
|
61
65
|
error: z.string().optional().describe("Error message if execution failed")
|
|
62
66
|
}).strict().describe("Tool execution response");
|
|
63
67
|
const ServerConfigResponseSchema = z.object({
|
|
64
68
|
name: z.string().describe("Server name"),
|
|
65
69
|
config: McpServerConfigSchema.describe("Server configuration")
|
|
66
70
|
}).strict().describe("MCP server configuration response");
|
|
71
|
+
const ServerResourceSchema = z.object({
|
|
72
|
+
uri: z.string().describe("Resolved resource URI for this server"),
|
|
73
|
+
name: z.string().describe("Resource display name"),
|
|
74
|
+
originalUri: z.string().describe("Original MCP resource URI"),
|
|
75
|
+
serverName: z.string().describe("Owning MCP server name")
|
|
76
|
+
}).strict().describe("Resource exposed by a specific MCP server");
|
|
67
77
|
const ResourcesListResponseSchema = z.object({
|
|
68
78
|
success: z.boolean().describe("Success indicator"),
|
|
69
|
-
resources: z.array(
|
|
79
|
+
resources: z.array(ServerResourceSchema).describe("Array of available resources")
|
|
70
80
|
}).strict().describe("List of resources from MCP server");
|
|
71
81
|
const ResourceContentSchema = z.object({
|
|
72
|
-
content:
|
|
82
|
+
content: JsonValueSchema.describe("Resource content data")
|
|
73
83
|
}).strict().describe("Resource content wrapper");
|
|
74
84
|
const ResourceContentResponseSchema = z.object({
|
|
75
85
|
success: z.boolean().describe("Success indicator"),
|
|
76
86
|
data: ResourceContentSchema.describe("Resource content")
|
|
77
87
|
}).strict().describe("Resource content response");
|
|
78
|
-
function
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
const listServersRoute = createRoute({
|
|
95
|
-
method: "get",
|
|
96
|
-
path: "/mcp/servers",
|
|
97
|
-
summary: "List MCP Servers",
|
|
98
|
-
description: "Gets a list of all connected and failed MCP servers",
|
|
99
|
-
tags: ["mcp"],
|
|
100
|
-
responses: {
|
|
101
|
-
200: {
|
|
102
|
-
description: "Servers list",
|
|
103
|
-
content: { "application/json": { schema: ServersListResponseSchema } }
|
|
104
|
-
}
|
|
105
|
-
}
|
|
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") })
|
|
88
|
+
function mountMcpSubrouter(app, router) {
|
|
89
|
+
app.route("/", router);
|
|
90
|
+
}
|
|
91
|
+
const addServerRoute = createRoute({
|
|
92
|
+
method: "post",
|
|
93
|
+
path: "/mcp/servers",
|
|
94
|
+
summary: "Add MCP Server",
|
|
95
|
+
description: "Connects a new MCP server dynamically",
|
|
96
|
+
tags: ["mcp"],
|
|
97
|
+
request: { body: { content: { "application/json": { schema: McpServerRequestSchema } } } },
|
|
98
|
+
responses: {
|
|
99
|
+
200: {
|
|
100
|
+
description: "Server connected",
|
|
101
|
+
content: { "application/json": { schema: ServerStatusResponseSchema } }
|
|
115
102
|
},
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
103
|
+
400: BadRequestErrorResponse,
|
|
104
|
+
500: InternalErrorResponse
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
const listServersRoute = createRoute({
|
|
108
|
+
method: "get",
|
|
109
|
+
path: "/mcp/servers",
|
|
110
|
+
summary: "List MCP Servers",
|
|
111
|
+
description: "Gets a list of all connected and failed MCP servers",
|
|
112
|
+
tags: ["mcp"],
|
|
113
|
+
responses: {
|
|
114
|
+
200: {
|
|
115
|
+
description: "Servers list",
|
|
116
|
+
content: { "application/json": { schema: ServersListResponseSchema } }
|
|
117
|
+
},
|
|
118
|
+
500: InternalErrorResponse
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
const getServerConfigRoute = createRoute({
|
|
122
|
+
method: "get",
|
|
123
|
+
path: "/mcp/servers/{serverId}/config",
|
|
124
|
+
summary: "Get MCP Server Config",
|
|
125
|
+
description: "Retrieves the configuration for a specific MCP server",
|
|
126
|
+
tags: ["mcp"],
|
|
127
|
+
request: {
|
|
128
|
+
params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
|
|
129
|
+
},
|
|
130
|
+
responses: {
|
|
131
|
+
200: {
|
|
132
|
+
description: "Server configuration",
|
|
133
|
+
content: { "application/json": { schema: ServerConfigResponseSchema } }
|
|
134
|
+
},
|
|
135
|
+
404: {
|
|
136
|
+
description: "Not found",
|
|
137
|
+
content: { "application/json": { schema: ApiErrorResponseSchema } }
|
|
122
138
|
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
const updateServerRoute = createRoute({
|
|
142
|
+
method: "put",
|
|
143
|
+
path: "/mcp/servers/{serverId}",
|
|
144
|
+
summary: "Update MCP Server",
|
|
145
|
+
description: "Updates configuration for an existing MCP server",
|
|
146
|
+
tags: ["mcp"],
|
|
147
|
+
request: {
|
|
148
|
+
params: z.object({ serverId: z.string().describe("The ID of the MCP server") }),
|
|
149
|
+
body: { content: { "application/json": { schema: McpServerUpdateSchema } } }
|
|
150
|
+
},
|
|
151
|
+
responses: {
|
|
152
|
+
200: {
|
|
153
|
+
description: "Server updated",
|
|
154
|
+
content: { "application/json": { schema: ServerStatusResponseSchema } }
|
|
133
155
|
},
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
content: { "application/json": { schema: ServerStatusResponseSchema } }
|
|
138
|
-
},
|
|
139
|
-
404: { description: "Not found" }
|
|
156
|
+
404: {
|
|
157
|
+
description: "Not found",
|
|
158
|
+
content: { "application/json": { schema: ApiErrorResponseSchema } }
|
|
140
159
|
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
const toolsRoute = createRoute({
|
|
163
|
+
method: "get",
|
|
164
|
+
path: "/mcp/servers/{serverId}/tools",
|
|
165
|
+
summary: "List Server Tools",
|
|
166
|
+
description: "Retrieves the list of tools available on a specific MCP server",
|
|
167
|
+
tags: ["mcp"],
|
|
168
|
+
request: {
|
|
169
|
+
params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
|
|
170
|
+
},
|
|
171
|
+
responses: {
|
|
172
|
+
200: {
|
|
173
|
+
description: "Tools list",
|
|
174
|
+
content: { "application/json": { schema: ToolsListResponseSchema } }
|
|
150
175
|
},
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
content: { "application/json": { schema: ToolsListResponseSchema } }
|
|
155
|
-
},
|
|
156
|
-
404: { description: "Not found" }
|
|
176
|
+
404: {
|
|
177
|
+
description: "Not found",
|
|
178
|
+
content: { "application/json": { schema: ApiErrorResponseSchema } }
|
|
157
179
|
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
const deleteServerRoute = createRoute({
|
|
183
|
+
method: "delete",
|
|
184
|
+
path: "/mcp/servers/{serverId}",
|
|
185
|
+
summary: "Remove MCP Server",
|
|
186
|
+
description: "Disconnects and removes an MCP server",
|
|
187
|
+
tags: ["mcp"],
|
|
188
|
+
request: {
|
|
189
|
+
params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
|
|
190
|
+
},
|
|
191
|
+
responses: {
|
|
192
|
+
200: {
|
|
193
|
+
description: "Disconnected",
|
|
194
|
+
content: { "application/json": { schema: DisconnectResponseSchema } }
|
|
167
195
|
},
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
content: { "application/json": { schema: DisconnectResponseSchema } }
|
|
172
|
-
},
|
|
173
|
-
404: { description: "Not found" }
|
|
196
|
+
404: {
|
|
197
|
+
description: "Not found",
|
|
198
|
+
content: { "application/json": { schema: ApiErrorResponseSchema } }
|
|
174
199
|
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
const restartServerRoute = createRoute({
|
|
203
|
+
method: "post",
|
|
204
|
+
path: "/mcp/servers/{serverId}/restart",
|
|
205
|
+
summary: "Restart MCP Server",
|
|
206
|
+
description: "Restarts a connected MCP server",
|
|
207
|
+
tags: ["mcp"],
|
|
208
|
+
request: {
|
|
209
|
+
params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
|
|
210
|
+
},
|
|
211
|
+
responses: {
|
|
212
|
+
200: {
|
|
213
|
+
description: "Server restarted",
|
|
214
|
+
content: { "application/json": { schema: RestartResponseSchema } }
|
|
184
215
|
},
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
content: { "application/json": { schema: RestartResponseSchema } }
|
|
189
|
-
},
|
|
190
|
-
404: { description: "Not found" }
|
|
216
|
+
404: {
|
|
217
|
+
description: "Not found",
|
|
218
|
+
content: { "application/json": { schema: ApiErrorResponseSchema } }
|
|
191
219
|
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
const execToolRoute = createRoute({
|
|
223
|
+
method: "post",
|
|
224
|
+
path: "/mcp/servers/{serverId}/tools/{toolName}/execute",
|
|
225
|
+
summary: "Execute MCP Tool",
|
|
226
|
+
description: "Executes a tool on an MCP server directly",
|
|
227
|
+
tags: ["mcp"],
|
|
228
|
+
request: {
|
|
229
|
+
params: z.object({
|
|
230
|
+
serverId: z.string().describe("The ID of the MCP server"),
|
|
231
|
+
toolName: z.string().describe("The name of the tool to execute")
|
|
232
|
+
}),
|
|
233
|
+
body: { content: { "application/json": { schema: ExecuteToolBodySchema } } }
|
|
234
|
+
},
|
|
235
|
+
responses: {
|
|
236
|
+
200: {
|
|
237
|
+
description: "Tool executed",
|
|
238
|
+
content: { "application/json": { schema: ToolExecutionResponseSchema } }
|
|
205
239
|
},
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
content: { "application/json": { schema: ToolExecutionResponseSchema } }
|
|
210
|
-
},
|
|
211
|
-
404: { description: "Not found" }
|
|
240
|
+
404: {
|
|
241
|
+
description: "Not found",
|
|
242
|
+
content: { "application/json": { schema: ApiErrorResponseSchema } }
|
|
212
243
|
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
const listResourcesRoute = createRoute({
|
|
247
|
+
method: "get",
|
|
248
|
+
path: "/mcp/servers/{serverId}/resources",
|
|
249
|
+
summary: "List Server Resources",
|
|
250
|
+
description: "Retrieves all resources available from a specific MCP server",
|
|
251
|
+
tags: ["mcp"],
|
|
252
|
+
request: {
|
|
253
|
+
params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
|
|
254
|
+
},
|
|
255
|
+
responses: {
|
|
256
|
+
200: {
|
|
257
|
+
description: "Server resources",
|
|
258
|
+
content: { "application/json": { schema: ResourcesListResponseSchema } }
|
|
222
259
|
},
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
content: { "application/json": { schema: ResourcesListResponseSchema } }
|
|
227
|
-
},
|
|
228
|
-
404: { description: "Not found" }
|
|
260
|
+
404: {
|
|
261
|
+
description: "Not found",
|
|
262
|
+
content: { "application/json": { schema: ApiErrorResponseSchema } }
|
|
229
263
|
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
const getResourceContentRoute = createRoute({
|
|
267
|
+
method: "get",
|
|
268
|
+
path: "/mcp/servers/{serverId}/resources/{resourceId}/content",
|
|
269
|
+
summary: "Read Server Resource Content",
|
|
270
|
+
description: "Reads content from a specific resource on an MCP server. This endpoint automatically constructs the qualified URI format (mcp:serverId:resourceId)",
|
|
271
|
+
tags: ["mcp"],
|
|
272
|
+
request: {
|
|
273
|
+
params: z.object({
|
|
274
|
+
serverId: z.string().describe("The ID of the MCP server"),
|
|
275
|
+
resourceId: z.string().min(1, "Resource ID is required").transform((encoded) => decodeURIComponent(encoded)).describe("The URI-encoded resource identifier on that server")
|
|
276
|
+
})
|
|
277
|
+
},
|
|
278
|
+
responses: {
|
|
279
|
+
200: {
|
|
280
|
+
description: "Resource content",
|
|
281
|
+
content: { "application/json": { schema: ResourceContentResponseSchema } }
|
|
242
282
|
},
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
content: { "application/json": { schema: ResourceContentResponseSchema } }
|
|
247
|
-
},
|
|
248
|
-
404: { description: "Not found" }
|
|
283
|
+
404: {
|
|
284
|
+
description: "Not found",
|
|
285
|
+
content: { "application/json": { schema: ApiErrorResponseSchema } }
|
|
249
286
|
}
|
|
250
|
-
}
|
|
251
|
-
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
function createMcpRouter(getAgent, getAgentConfigPath) {
|
|
290
|
+
const app = new OpenAPIHono();
|
|
291
|
+
const serverRegistrationRouter = new OpenAPIHono().openapi(addServerRoute, async (ctx) => {
|
|
252
292
|
const agent = await getAgent(ctx);
|
|
253
293
|
const { name, config, persistToAgent } = ctx.req.valid("json");
|
|
254
294
|
await agent.addMcpServer(name, config);
|
|
@@ -294,22 +334,23 @@ function createMcpRouter(getAgent, getAgentConfigPath) {
|
|
|
294
334
|
for (const name of Object.keys(failedConnections)) {
|
|
295
335
|
servers.push({ id: name, name, status: "error" });
|
|
296
336
|
}
|
|
297
|
-
return ctx.json({ servers });
|
|
337
|
+
return ctx.json({ servers }, 200);
|
|
298
338
|
}).openapi(getServerConfigRoute, async (ctx) => {
|
|
299
339
|
const agent = await getAgent(ctx);
|
|
300
340
|
const { serverId } = ctx.req.valid("param");
|
|
301
341
|
const config = agent.getMcpServerConfig(serverId);
|
|
302
342
|
if (!config) {
|
|
303
|
-
|
|
343
|
+
throw MCPError.serverNotFound(serverId);
|
|
304
344
|
}
|
|
305
|
-
return ctx.json({ name: serverId, config }, 200);
|
|
306
|
-
})
|
|
345
|
+
return ctx.json({ name: serverId, config: McpServerConfigSchema.parse(config) }, 200);
|
|
346
|
+
});
|
|
347
|
+
const serverUpdateRouter = new OpenAPIHono().openapi(updateServerRoute, async (ctx) => {
|
|
307
348
|
const agent = await getAgent(ctx);
|
|
308
349
|
const { serverId } = ctx.req.valid("param");
|
|
309
350
|
const { config, persistToAgent } = ctx.req.valid("json");
|
|
310
351
|
const existingConfig = agent.getMcpServerConfig(serverId);
|
|
311
352
|
if (!existingConfig) {
|
|
312
|
-
|
|
353
|
+
throw MCPError.serverNotFound(serverId);
|
|
313
354
|
}
|
|
314
355
|
await agent.updateMcpServer(serverId, config);
|
|
315
356
|
if (persistToAgent === true) {
|
|
@@ -329,89 +370,122 @@ function createMcpRouter(getAgent, getAgentConfigPath) {
|
|
|
329
370
|
logger.info(`Saved server '${serverId}' to agent configuration file`);
|
|
330
371
|
} catch (saveError) {
|
|
331
372
|
const errorMessage = saveError instanceof Error ? saveError.message : String(saveError);
|
|
332
|
-
logger.warn(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
);
|
|
373
|
+
logger.warn(`Failed to persist MCP server '${serverId}' update: ${errorMessage}`, {
|
|
374
|
+
error: saveError
|
|
375
|
+
});
|
|
336
376
|
}
|
|
337
377
|
}
|
|
338
378
|
const status = config.enabled === false ? "registered" : "connected";
|
|
339
379
|
return ctx.json({ status, name: serverId }, 200);
|
|
340
|
-
})
|
|
380
|
+
});
|
|
381
|
+
const serverToolsRouter = new OpenAPIHono().openapi(toolsRoute, async (ctx) => {
|
|
341
382
|
const agent = await getAgent(ctx);
|
|
342
383
|
const { serverId } = ctx.req.valid("param");
|
|
343
384
|
const client = agent.getMcpClients().get(serverId);
|
|
344
385
|
if (!client) {
|
|
345
|
-
|
|
386
|
+
throw MCPError.serverNotFound(serverId);
|
|
346
387
|
}
|
|
347
388
|
const toolsMap = await client.getTools();
|
|
348
389
|
const tools = Object.entries(toolsMap).map(([toolName, toolDef]) => ({
|
|
349
390
|
id: toolName,
|
|
350
391
|
name: toolName,
|
|
351
392
|
description: toolDef.description || "",
|
|
352
|
-
inputSchema: toolDef.parameters,
|
|
353
|
-
_meta: toolDef._meta
|
|
393
|
+
inputSchema: toolDef.parameters === void 0 ? void 0 : ToolInputSchema.parse(toolDef.parameters),
|
|
394
|
+
_meta: toolDef._meta === void 0 ? void 0 : JsonObjectSchema.parse(toolDef._meta)
|
|
354
395
|
}));
|
|
355
|
-
|
|
356
|
-
|
|
396
|
+
const response = { tools };
|
|
397
|
+
return ctx.json(response, 200);
|
|
398
|
+
});
|
|
399
|
+
const deleteServerRouter = new OpenAPIHono().openapi(deleteServerRoute, async (ctx) => {
|
|
357
400
|
const agent = await getAgent(ctx);
|
|
358
401
|
const { serverId } = ctx.req.valid("param");
|
|
359
402
|
const clientExists = agent.getMcpClients().has(serverId) || agent.getMcpFailedConnections()[serverId];
|
|
360
403
|
if (!clientExists) {
|
|
361
|
-
|
|
404
|
+
throw MCPError.serverNotFound(serverId);
|
|
362
405
|
}
|
|
363
406
|
await agent.removeMcpServer(serverId);
|
|
364
|
-
|
|
365
|
-
|
|
407
|
+
const response = { status: "disconnected", id: serverId };
|
|
408
|
+
return ctx.json(response, 200);
|
|
409
|
+
});
|
|
410
|
+
const restartServerRouter = new OpenAPIHono().openapi(restartServerRoute, async (ctx) => {
|
|
366
411
|
const agent = await getAgent(ctx);
|
|
367
412
|
const { serverId } = ctx.req.valid("param");
|
|
368
413
|
logger.info(`Received request to POST /api/mcp/servers/${serverId}/restart`);
|
|
369
414
|
const clientExists = agent.getMcpClients().has(serverId);
|
|
370
415
|
if (!clientExists) {
|
|
371
416
|
logger.warn(`Attempted to restart non-existent server: ${serverId}`);
|
|
372
|
-
|
|
417
|
+
throw MCPError.serverNotFound(serverId);
|
|
373
418
|
}
|
|
374
419
|
await agent.restartMcpServer(serverId);
|
|
375
|
-
|
|
376
|
-
|
|
420
|
+
const response = { status: "restarted", id: serverId };
|
|
421
|
+
return ctx.json(response, 200);
|
|
422
|
+
});
|
|
423
|
+
const execToolRouter = new OpenAPIHono().openapi(execToolRoute, async (ctx) => {
|
|
377
424
|
const agent = await getAgent(ctx);
|
|
378
425
|
const { serverId, toolName } = ctx.req.valid("param");
|
|
379
426
|
const body = ctx.req.valid("json");
|
|
380
427
|
const client = agent.getMcpClients().get(serverId);
|
|
381
428
|
if (!client) {
|
|
382
|
-
|
|
429
|
+
throw MCPError.serverNotFound(serverId);
|
|
383
430
|
}
|
|
384
431
|
try {
|
|
385
432
|
const rawResult = await client.callTool(toolName, body);
|
|
386
|
-
|
|
433
|
+
const response = {
|
|
434
|
+
success: true,
|
|
435
|
+
data: JsonValueSchema.parse(rawResult)
|
|
436
|
+
};
|
|
437
|
+
return ctx.json(response, 200);
|
|
387
438
|
} catch (error) {
|
|
388
439
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
389
440
|
logger.error(
|
|
390
441
|
`Tool execution failed for '${toolName}' on server '${serverId}': ${errorMessage}`,
|
|
391
442
|
{ error }
|
|
392
443
|
);
|
|
393
|
-
|
|
444
|
+
const response = {
|
|
445
|
+
success: false,
|
|
446
|
+
error: errorMessage
|
|
447
|
+
};
|
|
448
|
+
return ctx.json(response, 200);
|
|
394
449
|
}
|
|
395
|
-
})
|
|
450
|
+
});
|
|
451
|
+
const listResourcesRouter = new OpenAPIHono().openapi(listResourcesRoute, async (ctx) => {
|
|
396
452
|
const agent = await getAgent(ctx);
|
|
397
453
|
const { serverId } = ctx.req.valid("param");
|
|
398
454
|
const client = agent.getMcpClients().get(serverId);
|
|
399
455
|
if (!client) {
|
|
400
|
-
|
|
456
|
+
throw MCPError.serverNotFound(serverId);
|
|
401
457
|
}
|
|
402
458
|
const resources = await agent.listResourcesForServer(serverId);
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const agent = await getAgent(ctx);
|
|
406
|
-
const { serverId, resourceId } = ctx.req.valid("param");
|
|
407
|
-
const client = agent.getMcpClients().get(serverId);
|
|
408
|
-
if (!client) {
|
|
409
|
-
return ctx.json({ error: `Server '${serverId}' not found` }, 404);
|
|
410
|
-
}
|
|
411
|
-
const qualifiedUri = `mcp:${serverId}:${resourceId}`;
|
|
412
|
-
const content = await agent.readResource(qualifiedUri);
|
|
413
|
-
return ctx.json({ success: true, data: { content } });
|
|
459
|
+
const response = { success: true, resources };
|
|
460
|
+
return ctx.json(response, 200);
|
|
414
461
|
});
|
|
462
|
+
const getResourceContentRouter = new OpenAPIHono().openapi(
|
|
463
|
+
getResourceContentRoute,
|
|
464
|
+
async (ctx) => {
|
|
465
|
+
const agent = await getAgent(ctx);
|
|
466
|
+
const { serverId, resourceId } = ctx.req.valid("param");
|
|
467
|
+
const client = agent.getMcpClients().get(serverId);
|
|
468
|
+
if (!client) {
|
|
469
|
+
throw MCPError.serverNotFound(serverId);
|
|
470
|
+
}
|
|
471
|
+
const qualifiedUri = `mcp:${serverId}:${resourceId}`;
|
|
472
|
+
const content = await agent.readResource(qualifiedUri);
|
|
473
|
+
const response = {
|
|
474
|
+
success: true,
|
|
475
|
+
data: { content: JsonValueSchema.parse(content) }
|
|
476
|
+
};
|
|
477
|
+
return ctx.json(response, 200);
|
|
478
|
+
}
|
|
479
|
+
);
|
|
480
|
+
mountMcpSubrouter(app, serverRegistrationRouter);
|
|
481
|
+
mountMcpSubrouter(app, serverUpdateRouter);
|
|
482
|
+
mountMcpSubrouter(app, serverToolsRouter);
|
|
483
|
+
mountMcpSubrouter(app, deleteServerRouter);
|
|
484
|
+
mountMcpSubrouter(app, restartServerRouter);
|
|
485
|
+
mountMcpSubrouter(app, execToolRouter);
|
|
486
|
+
mountMcpSubrouter(app, listResourcesRouter);
|
|
487
|
+
mountMcpSubrouter(app, getResourceContentRouter);
|
|
488
|
+
return app;
|
|
415
489
|
}
|
|
416
490
|
export {
|
|
417
491
|
createMcpRouter
|