@ai-sdk/mcp 2.0.0-canary.42 → 2.0.0-canary.44
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 +14 -0
- package/dist/index.d.ts +72 -1
- package/dist/index.js +132 -12
- package/dist/index.js.map +1 -1
- package/dist/mcp-stdio/index.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +11 -0
- package/src/tool/index.ts +1 -0
- package/src/tool/mcp-apps.ts +254 -0
- package/src/tool/mcp-client.ts +38 -15
- package/src/tool/mock-mcp-transport.ts +1 -0
- package/src/tool/types.ts +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @ai-sdk/mcp
|
|
2
2
|
|
|
3
|
+
## 2.0.0-canary.44
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 611f621: feat(mcp): feat(mcp): add support for MCP Apps
|
|
8
|
+
|
|
9
|
+
## 2.0.0-canary.43
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- f634bac: feat(mcp): add new McpProviderMetadata type
|
|
14
|
+
- Updated dependencies [f634bac]
|
|
15
|
+
- @ai-sdk/provider-utils@5.0.0-canary.35
|
|
16
|
+
|
|
3
17
|
## 2.0.0-canary.42
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -258,6 +258,12 @@ type MCPTransportConfig = {
|
|
|
258
258
|
fetch?: FetchFunction;
|
|
259
259
|
};
|
|
260
260
|
|
|
261
|
+
type McpProviderMetadata = {
|
|
262
|
+
clientName?: string;
|
|
263
|
+
title?: string;
|
|
264
|
+
toolName?: string;
|
|
265
|
+
app?: JSONObject;
|
|
266
|
+
};
|
|
261
267
|
/** MCP tool metadata - keys should follow MCP _meta key format specification */
|
|
262
268
|
declare const ToolMetaSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
263
269
|
type ToolMeta = z.infer<typeof ToolMetaSchema>;
|
|
@@ -527,6 +533,14 @@ interface MCPClient {
|
|
|
527
533
|
params?: PaginatedRequest['params'];
|
|
528
534
|
options?: RequestOptions;
|
|
529
535
|
}): Promise<ListToolsResult>;
|
|
536
|
+
/**
|
|
537
|
+
* Calls a tool on the MCP server.
|
|
538
|
+
*/
|
|
539
|
+
callTool(args: {
|
|
540
|
+
name: string;
|
|
541
|
+
arguments?: Record<string, unknown>;
|
|
542
|
+
options?: RequestOptions;
|
|
543
|
+
}): Promise<CallToolResult>;
|
|
530
544
|
/**
|
|
531
545
|
* Creates AI SDK tools from tool definitions.
|
|
532
546
|
*/
|
|
@@ -557,4 +571,61 @@ interface MCPClient {
|
|
|
557
571
|
close: () => Promise<void>;
|
|
558
572
|
}
|
|
559
573
|
|
|
560
|
-
|
|
574
|
+
/**
|
|
575
|
+
* MIME type for HTML resources that are meant to be rendered as MCP Apps.
|
|
576
|
+
*/
|
|
577
|
+
declare const MCP_APP_MIME_TYPE: "text/html;profile=mcp-app";
|
|
578
|
+
/**
|
|
579
|
+
* Client capabilities to pass to `createMCPClient` when the host supports MCP Apps.
|
|
580
|
+
*/
|
|
581
|
+
declare const mcpAppClientCapabilities: {
|
|
582
|
+
readonly extensions: {
|
|
583
|
+
readonly "io.modelcontextprotocol/ui": {
|
|
584
|
+
readonly mimeTypes: readonly ["text/html;profile=mcp-app"];
|
|
585
|
+
};
|
|
586
|
+
};
|
|
587
|
+
};
|
|
588
|
+
/**
|
|
589
|
+
* Content security policy metadata requested by an MCP App resource.
|
|
590
|
+
*/
|
|
591
|
+
type MCPAppResourceCSP = {
|
|
592
|
+
connectDomains?: string[];
|
|
593
|
+
resourceDomains?: string[];
|
|
594
|
+
frameDomains?: string[];
|
|
595
|
+
[key: string]: unknown;
|
|
596
|
+
};
|
|
597
|
+
/**
|
|
598
|
+
* Host rendering metadata from an MCP App resource.
|
|
599
|
+
*/
|
|
600
|
+
type MCPAppResourceMeta = {
|
|
601
|
+
prefersBorder?: boolean;
|
|
602
|
+
csp?: MCPAppResourceCSP;
|
|
603
|
+
permissions?: Record<string, unknown>;
|
|
604
|
+
[key: string]: unknown;
|
|
605
|
+
};
|
|
606
|
+
/**
|
|
607
|
+
* HTML and metadata needed by a host to render an MCP App.
|
|
608
|
+
*/
|
|
609
|
+
type MCPAppResource = {
|
|
610
|
+
uri: string;
|
|
611
|
+
mimeType: typeof MCP_APP_MIME_TYPE;
|
|
612
|
+
html: string;
|
|
613
|
+
meta?: MCPAppResourceMeta;
|
|
614
|
+
};
|
|
615
|
+
/**
|
|
616
|
+
* Splits tool definitions into model-visible tools and app-visible tools.
|
|
617
|
+
*/
|
|
618
|
+
declare function splitMCPAppTools(definitions: ListToolsResult): {
|
|
619
|
+
modelVisible: ListToolsResult;
|
|
620
|
+
appVisible: ListToolsResult;
|
|
621
|
+
};
|
|
622
|
+
/**
|
|
623
|
+
* Reads a `ui://` resource from an MCP server and normalizes it for rendering.
|
|
624
|
+
*/
|
|
625
|
+
declare function readMCPAppResource({ client, uri, options, }: {
|
|
626
|
+
client: Pick<MCPClient, 'readResource'>;
|
|
627
|
+
uri: string;
|
|
628
|
+
options?: RequestOptions;
|
|
629
|
+
}): Promise<MCPAppResource>;
|
|
630
|
+
|
|
631
|
+
export { type CallToolResult, type Configuration, type ElicitResult, ElicitResultSchema, type ElicitationRequest, ElicitationRequestSchema, type JSONRPCError, type JSONRPCMessage, type JSONRPCNotification, type JSONRPCRequest, type JSONRPCResponse, type ListToolsResult, type MCPAppResource, type MCPAppResourceCSP, type MCPAppResourceMeta, type MCPClient, type ClientCapabilities as MCPClientCapabilities, type MCPClientConfig, type MCPTransport, MCP_APP_MIME_TYPE, type McpProviderMetadata, type OAuthClientInformation, type OAuthClientMetadata, type OAuthClientProvider, type OAuthTokens, UnauthorizedError, auth, createMCPClient, type MCPClient as experimental_MCPClient, type ClientCapabilities as experimental_MCPClientCapabilities, type MCPClientConfig as experimental_MCPClientConfig, createMCPClient as experimental_createMCPClient, mcpAppClientCapabilities, readMCPAppResource, splitMCPAppTools };
|
package/dist/index.js
CHANGED
|
@@ -1618,6 +1618,112 @@ function isCustomMcpTransport(transport) {
|
|
|
1618
1618
|
return "start" in transport && typeof transport.start === "function" && "send" in transport && typeof transport.send === "function" && "close" in transport && typeof transport.close === "function";
|
|
1619
1619
|
}
|
|
1620
1620
|
|
|
1621
|
+
// src/tool/mcp-apps.ts
|
|
1622
|
+
import { isJSONObject } from "@ai-sdk/provider";
|
|
1623
|
+
import { convertBase64ToUint8Array } from "@ai-sdk/provider-utils";
|
|
1624
|
+
var MCP_APP_EXTENSION_NAME = "io.modelcontextprotocol/ui";
|
|
1625
|
+
var MCP_APP_MIME_TYPE = "text/html;profile=mcp-app";
|
|
1626
|
+
var MCP_APP_LEGACY_RESOURCE_URI_META_KEY = "ui/resourceUri";
|
|
1627
|
+
var mcpAppClientCapabilities = {
|
|
1628
|
+
extensions: {
|
|
1629
|
+
[MCP_APP_EXTENSION_NAME]: {
|
|
1630
|
+
mimeTypes: [MCP_APP_MIME_TYPE]
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
};
|
|
1634
|
+
function getToolUiMeta(meta) {
|
|
1635
|
+
const uiMeta = meta == null ? void 0 : meta.ui;
|
|
1636
|
+
return isJSONObject(uiMeta) ? uiMeta : void 0;
|
|
1637
|
+
}
|
|
1638
|
+
function getResourceUiMeta(meta) {
|
|
1639
|
+
const resourceMeta = isJSONObject(meta) ? meta : void 0;
|
|
1640
|
+
const rawUiMeta = resourceMeta == null ? void 0 : resourceMeta.ui;
|
|
1641
|
+
const uiMeta = isJSONObject(rawUiMeta) ? rawUiMeta : void 0;
|
|
1642
|
+
return uiMeta;
|
|
1643
|
+
}
|
|
1644
|
+
function parseVisibility(value) {
|
|
1645
|
+
return Array.isArray(value) ? value.filter(
|
|
1646
|
+
(v) => v === "model" || v === "app"
|
|
1647
|
+
) : void 0;
|
|
1648
|
+
}
|
|
1649
|
+
function getMCPAppToolMeta(tool2) {
|
|
1650
|
+
var _a3, _b3;
|
|
1651
|
+
const uiMeta = getToolUiMeta(tool2._meta);
|
|
1652
|
+
const resourceUri = (_b3 = uiMeta == null ? void 0 : uiMeta.resourceUri) != null ? _b3 : (_a3 = tool2._meta) == null ? void 0 : _a3[MCP_APP_LEGACY_RESOURCE_URI_META_KEY];
|
|
1653
|
+
const visibility = parseVisibility(uiMeta == null ? void 0 : uiMeta.visibility);
|
|
1654
|
+
if (resourceUri !== void 0) {
|
|
1655
|
+
if (typeof resourceUri !== "string" || !resourceUri.startsWith("ui://")) {
|
|
1656
|
+
throw new Error(
|
|
1657
|
+
`Invalid MCP App resource URI: ${JSON.stringify(resourceUri)}`
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1660
|
+
} else if (uiMeta == null) {
|
|
1661
|
+
return void 0;
|
|
1662
|
+
}
|
|
1663
|
+
return {
|
|
1664
|
+
...uiMeta,
|
|
1665
|
+
...resourceUri != null ? { resourceUri } : {},
|
|
1666
|
+
...visibility != null ? { visibility } : {}
|
|
1667
|
+
};
|
|
1668
|
+
}
|
|
1669
|
+
function splitMCPAppTools(definitions) {
|
|
1670
|
+
var _a3;
|
|
1671
|
+
const modelVisibleTools = [];
|
|
1672
|
+
const appVisibleTools = [];
|
|
1673
|
+
for (const tool2 of definitions.tools) {
|
|
1674
|
+
const visibility = (_a3 = getMCPAppToolMeta(tool2)) == null ? void 0 : _a3.visibility;
|
|
1675
|
+
if (visibility == null || visibility.includes("model")) {
|
|
1676
|
+
modelVisibleTools.push(tool2);
|
|
1677
|
+
}
|
|
1678
|
+
if ((visibility == null ? void 0 : visibility.includes("app")) === true) {
|
|
1679
|
+
appVisibleTools.push(tool2);
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
return {
|
|
1683
|
+
modelVisible: {
|
|
1684
|
+
...definitions,
|
|
1685
|
+
tools: modelVisibleTools
|
|
1686
|
+
},
|
|
1687
|
+
appVisible: {
|
|
1688
|
+
...definitions,
|
|
1689
|
+
tools: appVisibleTools
|
|
1690
|
+
}
|
|
1691
|
+
};
|
|
1692
|
+
}
|
|
1693
|
+
function getMCPAppResourceFromReadResult({
|
|
1694
|
+
uri,
|
|
1695
|
+
resource
|
|
1696
|
+
}) {
|
|
1697
|
+
const content = resource.contents.find((content2) => content2.uri === uri);
|
|
1698
|
+
if (content == null) {
|
|
1699
|
+
throw new Error(`MCP App resource not found in read result: ${uri}`);
|
|
1700
|
+
}
|
|
1701
|
+
if (content.mimeType !== MCP_APP_MIME_TYPE) {
|
|
1702
|
+
throw new Error(
|
|
1703
|
+
`Unsupported MCP App resource MIME type: ${content.mimeType}`
|
|
1704
|
+
);
|
|
1705
|
+
}
|
|
1706
|
+
const html = "text" in content && typeof content.text === "string" ? content.text : "blob" in content && typeof content.blob === "string" ? new TextDecoder().decode(convertBase64ToUint8Array(content.blob)) : void 0;
|
|
1707
|
+
if (html == null) {
|
|
1708
|
+
throw new Error(`Unsupported MCP App resource content format: ${uri}`);
|
|
1709
|
+
}
|
|
1710
|
+
const meta = getResourceUiMeta(content._meta);
|
|
1711
|
+
return { uri, mimeType: MCP_APP_MIME_TYPE, html, meta };
|
|
1712
|
+
}
|
|
1713
|
+
async function readMCPAppResource({
|
|
1714
|
+
client,
|
|
1715
|
+
uri,
|
|
1716
|
+
options
|
|
1717
|
+
}) {
|
|
1718
|
+
if (!uri.startsWith("ui://")) {
|
|
1719
|
+
throw new Error(`Unsupported MCP App resource URI: ${uri}`);
|
|
1720
|
+
}
|
|
1721
|
+
return getMCPAppResourceFromReadResult({
|
|
1722
|
+
uri,
|
|
1723
|
+
resource: await client.readResource({ uri, options })
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1621
1727
|
// src/tool/mcp-client.ts
|
|
1622
1728
|
var CLIENT_VERSION = "1.0.0";
|
|
1623
1729
|
function mcpToModelOutput({
|
|
@@ -1842,16 +1948,14 @@ var DefaultMCPClient = class {
|
|
|
1842
1948
|
}
|
|
1843
1949
|
async callTool({
|
|
1844
1950
|
name: name3,
|
|
1845
|
-
args,
|
|
1951
|
+
arguments: args = {},
|
|
1846
1952
|
options
|
|
1847
1953
|
}) {
|
|
1848
1954
|
try {
|
|
1849
1955
|
return this.request({
|
|
1850
1956
|
request: { method: "tools/call", params: { name: name3, arguments: args } },
|
|
1851
1957
|
resultSchema: CallToolResultSchema,
|
|
1852
|
-
options
|
|
1853
|
-
signal: options == null ? void 0 : options.abortSignal
|
|
1854
|
-
}
|
|
1958
|
+
options
|
|
1855
1959
|
});
|
|
1856
1960
|
} catch (error) {
|
|
1857
1961
|
throw error;
|
|
@@ -1967,10 +2071,26 @@ var DefaultMCPClient = class {
|
|
|
1967
2071
|
}
|
|
1968
2072
|
const self = this;
|
|
1969
2073
|
const outputSchema = schemas !== "automatic" ? (_a3 = schemas[name3]) == null ? void 0 : _a3.outputSchema : void 0;
|
|
2074
|
+
const appMeta = getMCPAppToolMeta({ _meta });
|
|
2075
|
+
const metadata = {
|
|
2076
|
+
clientName: this.clientInfo.name,
|
|
2077
|
+
toolName: name3,
|
|
2078
|
+
...resolvedTitle != null ? { title: resolvedTitle } : {},
|
|
2079
|
+
...(appMeta == null ? void 0 : appMeta.resourceUri) != null ? {
|
|
2080
|
+
app: {
|
|
2081
|
+
...appMeta,
|
|
2082
|
+
mimeType: MCP_APP_MIME_TYPE
|
|
2083
|
+
}
|
|
2084
|
+
} : {}
|
|
2085
|
+
};
|
|
1970
2086
|
const execute = async (args, options) => {
|
|
1971
2087
|
var _a4;
|
|
1972
2088
|
(_a4 = options == null ? void 0 : options.abortSignal) == null ? void 0 : _a4.throwIfAborted();
|
|
1973
|
-
const result = await self.callTool({
|
|
2089
|
+
const result = await self.callTool({
|
|
2090
|
+
name: name3,
|
|
2091
|
+
arguments: args,
|
|
2092
|
+
options: { signal: options == null ? void 0 : options.abortSignal }
|
|
2093
|
+
});
|
|
1974
2094
|
if (result.isError) {
|
|
1975
2095
|
return result;
|
|
1976
2096
|
}
|
|
@@ -1982,9 +2102,7 @@ var DefaultMCPClient = class {
|
|
|
1982
2102
|
const toolWithExecute = schemas === "automatic" ? dynamicTool({
|
|
1983
2103
|
description,
|
|
1984
2104
|
title: resolvedTitle,
|
|
1985
|
-
metadata
|
|
1986
|
-
clientName: this.clientInfo.name
|
|
1987
|
-
},
|
|
2105
|
+
metadata,
|
|
1988
2106
|
inputSchema: jsonSchema({
|
|
1989
2107
|
...inputSchema,
|
|
1990
2108
|
properties: (_b3 = inputSchema.properties) != null ? _b3 : {},
|
|
@@ -1995,9 +2113,7 @@ var DefaultMCPClient = class {
|
|
|
1995
2113
|
}) : tool({
|
|
1996
2114
|
description,
|
|
1997
2115
|
title: resolvedTitle,
|
|
1998
|
-
metadata
|
|
1999
|
-
clientName: this.clientInfo.name
|
|
2000
|
-
},
|
|
2116
|
+
metadata,
|
|
2001
2117
|
inputSchema: schemas[name3].inputSchema,
|
|
2002
2118
|
...outputSchema != null ? { outputSchema } : {},
|
|
2003
2119
|
execute,
|
|
@@ -2185,9 +2301,13 @@ var DefaultMCPClient = class {
|
|
|
2185
2301
|
export {
|
|
2186
2302
|
ElicitResultSchema,
|
|
2187
2303
|
ElicitationRequestSchema,
|
|
2304
|
+
MCP_APP_MIME_TYPE,
|
|
2188
2305
|
UnauthorizedError,
|
|
2189
2306
|
auth,
|
|
2190
2307
|
createMCPClient,
|
|
2191
|
-
createMCPClient as experimental_createMCPClient
|
|
2308
|
+
createMCPClient as experimental_createMCPClient,
|
|
2309
|
+
mcpAppClientCapabilities,
|
|
2310
|
+
readMCPAppResource,
|
|
2311
|
+
splitMCPAppTools
|
|
2192
2312
|
};
|
|
2193
2313
|
//# sourceMappingURL=index.js.map
|