@ai-sdk/mcp 1.0.4 → 1.0.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @ai-sdk/mcp
2
2
 
3
+ ## 1.0.6
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [34d1c8a]
8
+ - @ai-sdk/provider-utils@4.0.5
9
+
10
+ ## 1.0.5
11
+
12
+ ### Patch Changes
13
+
14
+ - 9cc0f88: feat(mcp): add support for structuredContent / outputSchema for typed tool outputs
15
+
3
16
  ## 1.0.4
4
17
 
5
18
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -247,18 +247,23 @@ declare const ToolMetaSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknow
247
247
  type ToolMeta = z.infer<typeof ToolMetaSchema>;
248
248
  type ToolSchemas = Record<string, {
249
249
  inputSchema: FlexibleSchema<JSONObject | unknown>;
250
+ outputSchema?: FlexibleSchema<JSONObject | unknown>;
250
251
  }> | 'automatic' | undefined;
251
252
  /** Base MCP tool type with execute and _meta */
252
- type McpToolBase<INPUT = unknown> = Tool<INPUT, CallToolResult> & Required<Pick<Tool<INPUT, CallToolResult>, 'execute'>> & {
253
+ type McpToolBase<INPUT = unknown, OUTPUT = CallToolResult> = Tool<INPUT, OUTPUT> & Required<Pick<Tool<INPUT, OUTPUT>, 'execute'>> & {
253
254
  _meta?: ToolMeta;
254
255
  };
255
256
  type McpToolSet<TOOL_SCHEMAS extends ToolSchemas = 'automatic'> = TOOL_SCHEMAS extends Record<string, {
256
257
  inputSchema: FlexibleSchema<any>;
258
+ outputSchema?: FlexibleSchema<any>;
257
259
  }> ? {
258
260
  [K in keyof TOOL_SCHEMAS]: TOOL_SCHEMAS[K] extends {
259
261
  inputSchema: FlexibleSchema<infer INPUT>;
260
- } ? McpToolBase<INPUT> : never;
261
- } : Record<string, McpToolBase<unknown>>;
262
+ outputSchema: FlexibleSchema<infer OUTPUT>;
263
+ } ? McpToolBase<INPUT, OUTPUT> : TOOL_SCHEMAS[K] extends {
264
+ inputSchema: FlexibleSchema<infer INPUT>;
265
+ } ? McpToolBase<INPUT, CallToolResult> : never;
266
+ } : Record<string, McpToolBase<unknown, CallToolResult>>;
262
267
  declare const BaseParamsSchema: z.ZodObject<{
263
268
  _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
264
269
  }, z.core.$loose>;
@@ -324,6 +329,7 @@ declare const CallToolResultSchema: z.ZodUnion<[z.ZodObject<{
324
329
  blob: z.ZodBase64;
325
330
  }, z.core.$loose>]>;
326
331
  }, z.core.$loose>]>>;
332
+ structuredContent: z.ZodOptional<z.ZodUnknown>;
327
333
  isError: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
328
334
  }, z.core.$loose>, z.ZodObject<{
329
335
  _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
package/dist/index.d.ts CHANGED
@@ -247,18 +247,23 @@ declare const ToolMetaSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknow
247
247
  type ToolMeta = z.infer<typeof ToolMetaSchema>;
248
248
  type ToolSchemas = Record<string, {
249
249
  inputSchema: FlexibleSchema<JSONObject | unknown>;
250
+ outputSchema?: FlexibleSchema<JSONObject | unknown>;
250
251
  }> | 'automatic' | undefined;
251
252
  /** Base MCP tool type with execute and _meta */
252
- type McpToolBase<INPUT = unknown> = Tool<INPUT, CallToolResult> & Required<Pick<Tool<INPUT, CallToolResult>, 'execute'>> & {
253
+ type McpToolBase<INPUT = unknown, OUTPUT = CallToolResult> = Tool<INPUT, OUTPUT> & Required<Pick<Tool<INPUT, OUTPUT>, 'execute'>> & {
253
254
  _meta?: ToolMeta;
254
255
  };
255
256
  type McpToolSet<TOOL_SCHEMAS extends ToolSchemas = 'automatic'> = TOOL_SCHEMAS extends Record<string, {
256
257
  inputSchema: FlexibleSchema<any>;
258
+ outputSchema?: FlexibleSchema<any>;
257
259
  }> ? {
258
260
  [K in keyof TOOL_SCHEMAS]: TOOL_SCHEMAS[K] extends {
259
261
  inputSchema: FlexibleSchema<infer INPUT>;
260
- } ? McpToolBase<INPUT> : never;
261
- } : Record<string, McpToolBase<unknown>>;
262
+ outputSchema: FlexibleSchema<infer OUTPUT>;
263
+ } ? McpToolBase<INPUT, OUTPUT> : TOOL_SCHEMAS[K] extends {
264
+ inputSchema: FlexibleSchema<infer INPUT>;
265
+ } ? McpToolBase<INPUT, CallToolResult> : never;
266
+ } : Record<string, McpToolBase<unknown, CallToolResult>>;
262
267
  declare const BaseParamsSchema: z.ZodObject<{
263
268
  _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
264
269
  }, z.core.$loose>;
@@ -324,6 +329,7 @@ declare const CallToolResultSchema: z.ZodUnion<[z.ZodObject<{
324
329
  blob: z.ZodBase64;
325
330
  }, z.core.$loose>]>;
326
331
  }, z.core.$loose>]>>;
332
+ structuredContent: z.ZodOptional<z.ZodUnknown>;
327
333
  isError: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
328
334
  }, z.core.$loose>, z.ZodObject<{
329
335
  _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
package/dist/index.js CHANGED
@@ -136,6 +136,10 @@ var ToolSchema = import_v4.z.object({
136
136
  type: import_v4.z.literal("object"),
137
137
  properties: import_v4.z.optional(import_v4.z.object({}).loose())
138
138
  }).loose(),
139
+ /**
140
+ * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema
141
+ */
142
+ outputSchema: import_v4.z.optional(import_v4.z.object({}).loose()),
139
143
  annotations: import_v4.z.optional(
140
144
  import_v4.z.object({
141
145
  title: import_v4.z.optional(import_v4.z.string())
@@ -198,6 +202,10 @@ var CallToolResultSchema = ResultSchema.extend({
198
202
  content: import_v4.z.array(
199
203
  import_v4.z.union([TextContentSchema, ImageContentSchema, EmbeddedResourceSchema])
200
204
  ),
205
+ /**
206
+ * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content
207
+ */
208
+ structuredContent: import_v4.z.optional(import_v4.z.unknown()),
201
209
  isError: import_v4.z.boolean().default(false).optional()
202
210
  }).or(
203
211
  ResultSchema.extend({
@@ -1862,7 +1870,7 @@ var DefaultMCPClient = class {
1862
1870
  async tools({
1863
1871
  schemas = "automatic"
1864
1872
  } = {}) {
1865
- var _a3;
1873
+ var _a3, _b3;
1866
1874
  const tools = {};
1867
1875
  try {
1868
1876
  const listToolsResult = await this.listTools();
@@ -1878,17 +1886,22 @@ var DefaultMCPClient = class {
1878
1886
  continue;
1879
1887
  }
1880
1888
  const self = this;
1889
+ const outputSchema = schemas !== "automatic" ? (_a3 = schemas[name3]) == null ? void 0 : _a3.outputSchema : void 0;
1881
1890
  const execute = async (args, options) => {
1882
1891
  var _a4;
1883
1892
  (_a4 = options == null ? void 0 : options.abortSignal) == null ? void 0 : _a4.throwIfAborted();
1884
- return self.callTool({ name: name3, args, options });
1893
+ const result = await self.callTool({ name: name3, args, options });
1894
+ if (outputSchema != null) {
1895
+ return self.extractStructuredContent(result, outputSchema, name3);
1896
+ }
1897
+ return result;
1885
1898
  };
1886
1899
  const toolWithExecute = schemas === "automatic" ? (0, import_provider_utils3.dynamicTool)({
1887
1900
  description,
1888
1901
  title,
1889
1902
  inputSchema: (0, import_provider_utils3.jsonSchema)({
1890
1903
  ...inputSchema,
1891
- properties: (_a3 = inputSchema.properties) != null ? _a3 : {},
1904
+ properties: (_b3 = inputSchema.properties) != null ? _b3 : {},
1892
1905
  additionalProperties: false
1893
1906
  }),
1894
1907
  execute
@@ -1896,6 +1909,7 @@ var DefaultMCPClient = class {
1896
1909
  description,
1897
1910
  title,
1898
1911
  inputSchema: schemas[name3].inputSchema,
1912
+ ...outputSchema != null ? { outputSchema } : {},
1899
1913
  execute
1900
1914
  });
1901
1915
  tools[name3] = { ...toolWithExecute, _meta };
@@ -1905,6 +1919,43 @@ var DefaultMCPClient = class {
1905
1919
  throw error;
1906
1920
  }
1907
1921
  }
1922
+ /**
1923
+ * Extracts and validates structuredContent from a tool result.
1924
+ */
1925
+ async extractStructuredContent(result, outputSchema, toolName) {
1926
+ if ("structuredContent" in result && result.structuredContent != null) {
1927
+ const validationResult = await (0, import_provider_utils3.safeValidateTypes)({
1928
+ value: result.structuredContent,
1929
+ schema: (0, import_provider_utils3.asSchema)(outputSchema)
1930
+ });
1931
+ if (!validationResult.success) {
1932
+ throw new MCPClientError({
1933
+ message: `Tool "${toolName}" returned structuredContent that does not match the expected outputSchema`,
1934
+ cause: validationResult.error
1935
+ });
1936
+ }
1937
+ return validationResult.value;
1938
+ }
1939
+ if ("content" in result && Array.isArray(result.content)) {
1940
+ const textContent = result.content.find((c) => c.type === "text");
1941
+ if (textContent && "text" in textContent) {
1942
+ const parseResult = await (0, import_provider_utils3.safeParseJSON)({
1943
+ text: textContent.text,
1944
+ schema: outputSchema
1945
+ });
1946
+ if (!parseResult.success) {
1947
+ throw new MCPClientError({
1948
+ message: `Tool "${toolName}" returned content that does not match the expected outputSchema`,
1949
+ cause: parseResult.error
1950
+ });
1951
+ }
1952
+ return parseResult.value;
1953
+ }
1954
+ }
1955
+ throw new MCPClientError({
1956
+ message: `Tool "${toolName}" did not return structuredContent or parseable text content`
1957
+ });
1958
+ }
1908
1959
  listResources({
1909
1960
  params,
1910
1961
  options