@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.
Files changed (111) hide show
  1. package/dist/a2a/jsonrpc/methods.cjs +1 -1
  2. package/dist/a2a/jsonrpc/methods.d.ts +14 -4
  3. package/dist/a2a/jsonrpc/methods.d.ts.map +1 -1
  4. package/dist/a2a/jsonrpc/methods.js +1 -1
  5. package/dist/hono/index.cjs +39 -8
  6. package/dist/hono/index.d.ts +43 -4503
  7. package/dist/hono/index.d.ts.map +1 -1
  8. package/dist/hono/index.js +42 -9
  9. package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -1
  10. package/dist/hono/routes/a2a-tasks.cjs +173 -34
  11. package/dist/hono/routes/a2a-tasks.d.ts +1 -498
  12. package/dist/hono/routes/a2a-tasks.d.ts.map +1 -1
  13. package/dist/hono/routes/a2a-tasks.js +177 -34
  14. package/dist/hono/routes/a2a.d.ts.map +1 -1
  15. package/dist/hono/routes/agents.cjs +410 -329
  16. package/dist/hono/routes/agents.d.ts +16048 -73
  17. package/dist/hono/routes/agents.d.ts.map +1 -1
  18. package/dist/hono/routes/agents.js +418 -330
  19. package/dist/hono/routes/approvals.cjs +103 -78
  20. package/dist/hono/routes/approvals.d.ts +2090 -112
  21. package/dist/hono/routes/approvals.d.ts.map +1 -1
  22. package/dist/hono/routes/approvals.js +108 -78
  23. package/dist/hono/routes/dexto-auth.cjs +40 -33
  24. package/dist/hono/routes/dexto-auth.d.ts +401 -2
  25. package/dist/hono/routes/dexto-auth.d.ts.map +1 -1
  26. package/dist/hono/routes/dexto-auth.js +40 -33
  27. package/dist/hono/routes/discovery.cjs +16 -14
  28. package/dist/hono/routes/discovery.d.ts +586 -1
  29. package/dist/hono/routes/discovery.d.ts.map +1 -1
  30. package/dist/hono/routes/discovery.js +16 -14
  31. package/dist/hono/routes/greeting.cjs +26 -22
  32. package/dist/hono/routes/greeting.d.ts +787 -3
  33. package/dist/hono/routes/greeting.d.ts.map +1 -1
  34. package/dist/hono/routes/greeting.js +26 -22
  35. package/dist/hono/routes/health.d.ts +1 -1
  36. package/dist/hono/routes/key.cjs +60 -52
  37. package/dist/hono/routes/key.d.ts +1597 -1
  38. package/dist/hono/routes/key.d.ts.map +1 -1
  39. package/dist/hono/routes/key.js +60 -52
  40. package/dist/hono/routes/llm.cjs +381 -348
  41. package/dist/hono/routes/llm.d.ts +12137 -87
  42. package/dist/hono/routes/llm.d.ts.map +1 -1
  43. package/dist/hono/routes/llm.js +385 -348
  44. package/dist/hono/routes/mcp.cjs +273 -212
  45. package/dist/hono/routes/mcp.d.ts +6605 -316
  46. package/dist/hono/routes/mcp.d.ts.map +1 -1
  47. package/dist/hono/routes/mcp.js +287 -213
  48. package/dist/hono/routes/memory.cjs +102 -89
  49. package/dist/hono/routes/memory.d.ts +5368 -4
  50. package/dist/hono/routes/memory.d.ts.map +1 -1
  51. package/dist/hono/routes/memory.js +108 -90
  52. package/dist/hono/routes/messages.cjs +171 -164
  53. package/dist/hono/routes/messages.d.ts +3899 -10
  54. package/dist/hono/routes/messages.d.ts.map +1 -1
  55. package/dist/hono/routes/messages.js +181 -165
  56. package/dist/hono/routes/models.cjs +106 -64
  57. package/dist/hono/routes/models.d.ts +2874 -1
  58. package/dist/hono/routes/models.d.ts.map +1 -1
  59. package/dist/hono/routes/models.js +108 -64
  60. package/dist/hono/routes/openrouter.cjs +79 -65
  61. package/dist/hono/routes/openrouter.d.ts +854 -1
  62. package/dist/hono/routes/openrouter.d.ts.map +1 -1
  63. package/dist/hono/routes/openrouter.js +79 -65
  64. package/dist/hono/routes/prompts.cjs +137 -104
  65. package/dist/hono/routes/prompts.d.ts +2820 -12
  66. package/dist/hono/routes/prompts.d.ts.map +1 -1
  67. package/dist/hono/routes/prompts.js +144 -105
  68. package/dist/hono/routes/queue.cjs +158 -132
  69. package/dist/hono/routes/queue.d.ts +5148 -13
  70. package/dist/hono/routes/queue.d.ts.map +1 -1
  71. package/dist/hono/routes/queue.js +168 -133
  72. package/dist/hono/routes/resources.cjs +65 -46
  73. package/dist/hono/routes/resources.d.ts +1983 -5
  74. package/dist/hono/routes/resources.d.ts.map +1 -1
  75. package/dist/hono/routes/resources.js +72 -47
  76. package/dist/hono/routes/schedules.cjs +233 -226
  77. package/dist/hono/routes/schedules.d.ts +4202 -26
  78. package/dist/hono/routes/schedules.d.ts.map +1 -1
  79. package/dist/hono/routes/schedules.js +233 -226
  80. package/dist/hono/routes/search.cjs +34 -30
  81. package/dist/hono/routes/search.d.ts +2837 -14
  82. package/dist/hono/routes/search.d.ts.map +1 -1
  83. package/dist/hono/routes/search.js +40 -31
  84. package/dist/hono/routes/sessions.cjs +404 -392
  85. package/dist/hono/routes/sessions.d.ts +16585 -30
  86. package/dist/hono/routes/sessions.d.ts.map +1 -1
  87. package/dist/hono/routes/sessions.js +408 -393
  88. package/dist/hono/routes/static.d.ts.map +1 -1
  89. package/dist/hono/routes/system-prompt.cjs +57 -61
  90. package/dist/hono/routes/system-prompt.d.ts +1228 -2
  91. package/dist/hono/routes/system-prompt.d.ts.map +1 -1
  92. package/dist/hono/routes/system-prompt.js +58 -62
  93. package/dist/hono/routes/tools.cjs +29 -34
  94. package/dist/hono/routes/tools.d.ts +1756 -7
  95. package/dist/hono/routes/tools.d.ts.map +1 -1
  96. package/dist/hono/routes/tools.js +33 -33
  97. package/dist/hono/routes/webhooks.cjs +159 -132
  98. package/dist/hono/routes/webhooks.d.ts +2504 -14
  99. package/dist/hono/routes/webhooks.d.ts.map +1 -1
  100. package/dist/hono/routes/webhooks.js +163 -132
  101. package/dist/hono/routes/workspaces.cjs +84 -79
  102. package/dist/hono/routes/workspaces.d.ts +2093 -2
  103. package/dist/hono/routes/workspaces.d.ts.map +1 -1
  104. package/dist/hono/routes/workspaces.js +89 -80
  105. package/dist/hono/schemas/responses.cjs +492 -235
  106. package/dist/hono/schemas/responses.d.ts +1461 -146
  107. package/dist/hono/schemas/responses.d.ts.map +1 -1
  108. package/dist/hono/schemas/responses.js +247 -9
  109. package/dist/hono/types.d.ts +11 -0
  110. package/dist/hono/types.d.ts.map +1 -1
  111. package/package.json +7 -7
@@ -1,7 +1,20 @@
1
1
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
- import { AgentError, logger, McpServerConfigSchema, MCP_CONNECTION_STATUSES } from "@dexto/core";
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 { ResourceSchema } from "../schemas/responses.js";
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 = z.record(z.unknown()).describe(
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: z.record(z.unknown()).optional().describe("Optional tool metadata (e.g., MCP Apps UI resource info)")
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: z.any().optional().describe("Tool execution result 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(ResourceSchema).describe("Array of available resources")
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: z.any().describe("Resource content data")
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 createMcpRouter(getAgent, getAgentConfigPath) {
79
- const app = new OpenAPIHono();
80
- const addServerRoute = createRoute({
81
- method: "post",
82
- path: "/mcp/servers",
83
- summary: "Add MCP Server",
84
- description: "Connects a new MCP server dynamically",
85
- tags: ["mcp"],
86
- request: { body: { content: { "application/json": { schema: McpServerRequestSchema } } } },
87
- responses: {
88
- 200: {
89
- description: "Server connected",
90
- content: { "application/json": { schema: ServerStatusResponseSchema } }
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
- responses: {
117
- 200: {
118
- description: "Server configuration",
119
- content: { "application/json": { schema: ServerConfigResponseSchema } }
120
- },
121
- 404: { description: "Not found" }
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
- 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 } } }
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
- responses: {
135
- 200: {
136
- description: "Server updated",
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
- const toolsRoute = createRoute({
143
- method: "get",
144
- path: "/mcp/servers/{serverId}/tools",
145
- summary: "List Server Tools",
146
- description: "Retrieves the list of tools available on a specific MCP server",
147
- tags: ["mcp"],
148
- request: {
149
- params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
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
- responses: {
152
- 200: {
153
- description: "Tools list",
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
- const deleteServerRoute = createRoute({
160
- method: "delete",
161
- path: "/mcp/servers/{serverId}",
162
- summary: "Remove MCP Server",
163
- description: "Disconnects and removes an MCP server",
164
- tags: ["mcp"],
165
- request: {
166
- params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
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
- responses: {
169
- 200: {
170
- description: "Disconnected",
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
- const restartServerRoute = createRoute({
177
- method: "post",
178
- path: "/mcp/servers/{serverId}/restart",
179
- summary: "Restart MCP Server",
180
- description: "Restarts a connected MCP server",
181
- tags: ["mcp"],
182
- request: {
183
- params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
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
- responses: {
186
- 200: {
187
- description: "Server restarted",
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
- const execToolRoute = createRoute({
194
- method: "post",
195
- path: "/mcp/servers/{serverId}/tools/{toolName}/execute",
196
- summary: "Execute MCP Tool",
197
- description: "Executes a tool on an MCP server directly",
198
- tags: ["mcp"],
199
- request: {
200
- params: z.object({
201
- serverId: z.string().describe("The ID of the MCP server"),
202
- toolName: z.string().describe("The name of the tool to execute")
203
- }),
204
- body: { content: { "application/json": { schema: ExecuteToolBodySchema } } }
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
- responses: {
207
- 200: {
208
- description: "Tool executed",
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
- const listResourcesRoute = createRoute({
215
- method: "get",
216
- path: "/mcp/servers/{serverId}/resources",
217
- summary: "List Server Resources",
218
- description: "Retrieves all resources available from a specific MCP server",
219
- tags: ["mcp"],
220
- request: {
221
- params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
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
- responses: {
224
- 200: {
225
- description: "Server resources",
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
- const getResourceContentRoute = createRoute({
232
- method: "get",
233
- path: "/mcp/servers/{serverId}/resources/{resourceId}/content",
234
- summary: "Read Server Resource Content",
235
- description: "Reads content from a specific resource on an MCP server. This endpoint automatically constructs the qualified URI format (mcp:serverId:resourceId)",
236
- tags: ["mcp"],
237
- request: {
238
- params: z.object({
239
- serverId: z.string().describe("The ID of the MCP server"),
240
- resourceId: z.string().min(1, "Resource ID is required").transform((encoded) => decodeURIComponent(encoded)).describe("The URI-encoded resource identifier on that server")
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
- responses: {
244
- 200: {
245
- description: "Resource content",
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
- return app.openapi(addServerRoute, async (ctx) => {
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
- return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
343
+ throw MCPError.serverNotFound(serverId);
304
344
  }
305
- return ctx.json({ name: serverId, config }, 200);
306
- }).openapi(updateServerRoute, async (ctx) => {
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
- return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
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
- `Failed to persist MCP server '${serverId}' update: ${errorMessage}`,
334
- { error: saveError }
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
- }).openapi(toolsRoute, async (ctx) => {
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
- return ctx.json({ error: `Server '${serverId}' not found` }, 404);
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
- return ctx.json({ tools });
356
- }).openapi(deleteServerRoute, async (ctx) => {
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
- return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
404
+ throw MCPError.serverNotFound(serverId);
362
405
  }
363
406
  await agent.removeMcpServer(serverId);
364
- return ctx.json({ status: "disconnected", id: serverId });
365
- }).openapi(restartServerRoute, async (ctx) => {
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
- return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
417
+ throw MCPError.serverNotFound(serverId);
373
418
  }
374
419
  await agent.restartMcpServer(serverId);
375
- return ctx.json({ status: "restarted", id: serverId });
376
- }).openapi(execToolRoute, async (ctx) => {
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
- return ctx.json({ success: false, error: `Server '${serverId}' not found` }, 404);
429
+ throw MCPError.serverNotFound(serverId);
383
430
  }
384
431
  try {
385
432
  const rawResult = await client.callTool(toolName, body);
386
- return ctx.json({ success: true, data: rawResult });
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
- return ctx.json({ success: false, error: errorMessage }, 200);
444
+ const response = {
445
+ success: false,
446
+ error: errorMessage
447
+ };
448
+ return ctx.json(response, 200);
394
449
  }
395
- }).openapi(listResourcesRoute, async (ctx) => {
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
- return ctx.json({ error: `Server '${serverId}' not found` }, 404);
456
+ throw MCPError.serverNotFound(serverId);
401
457
  }
402
458
  const resources = await agent.listResourcesForServer(serverId);
403
- return ctx.json({ success: true, resources });
404
- }).openapi(getResourceContentRoute, async (ctx) => {
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