Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,15 @@ resources:
## Getting Started

```bash
npm install -S @modelcontextprotocol/ext-apps
npm install -S @modelcontextprotocol/ext-apps \
@modelcontextprotocol/client @modelcontextprotocol/server @modelcontextprotocol/core
```

Peer dependencies are the MCP TypeScript SDK v2 packages
(`@modelcontextprotocol/client`, `/server`, `/core` at `2.0.0-beta.3`). Install
the ones your entry point needs — Views use `client` + `core`, server helpers
use `server`, and `app-bridge` uses all three.

**New here?** Start with the
[Quickstart Guide](https://apps.extensions.modelcontextprotocol.io/api/documents/Quickstart.html)
to build your first MCP App.
Expand Down
12 changes: 9 additions & 3 deletions build.bun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ function buildJs(
});
}

// zod is a peerDependency — keep it external so consumers share a single
// zod instance (instanceof ZodError / schema.extend() break with duplicate copies).
const PEER_EXTERNALS = ["@modelcontextprotocol/sdk", "zod"];
// Peer deps stay external so consumers share a single instance (zod
// instanceof / schema.extend() break with duplicates; MCP packages must
// match the host's installed v2 SDK). Bundled into *-with-deps variants.
const PEER_EXTERNALS = [
"@modelcontextprotocol/client",
"@modelcontextprotocol/core",
"@modelcontextprotocol/server",
"zod",
];

await Promise.all([
buildJs("src/app.ts", {
Expand Down
4 changes: 2 additions & 2 deletions docs/migrate_from_openai_apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ The server-side changes involve updating metadata structure and using helper fun
#### Before (OpenAI)

```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { McpServer } from "@modelcontextprotocol/server";
import { z } from "zod";

function createServer() {
Expand Down Expand Up @@ -126,7 +126,7 @@ function createServer() {
#### After (MCP Apps)

```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { McpServer } from "@modelcontextprotocol/server";
import {
registerAppTool,
registerAppResource,
Expand Down
9 changes: 3 additions & 6 deletions docs/patterns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@ import { randomUUID } from "node:crypto";
import type {
CallToolResult,
ReadResourceResult,
} from "@modelcontextprotocol/sdk/types.js";
import { ReadResourceResultSchema } from "@modelcontextprotocol/sdk/types.js";
} from "@modelcontextprotocol/server";
import { ReadResourceResultSchema } from "@modelcontextprotocol/core";
import type { McpUiHostContext } from "../src/types.js";
import { useEffect, useState } from "react";
import { useApp } from "../src/react/index.js";
import { registerAppTool } from "../src/server/index.js";
import {
McpServer,
ResourceTemplate,
} from "@modelcontextprotocol/sdk/server/mcp.js";
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/server";
import { z } from "zod";

/**
Expand Down
14 changes: 7 additions & 7 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Install the dependencies you'll need:

```bash
npm init -y
npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/sdk express cors
npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/server @modelcontextprotocol/node @modelcontextprotocol/express express cors
npm install -D typescript vite vite-plugin-singlefile @types/express @types/cors @types/node tsx concurrently cross-env
```

Expand Down Expand Up @@ -178,7 +178,7 @@ import {
registerAppTool,
RESOURCE_MIME_TYPE,
} from "@modelcontextprotocol/ext-apps/server";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { McpServer } from "@modelcontextprotocol/server";
import fs from "node:fs/promises";
import path from "node:path";

Expand Down Expand Up @@ -240,10 +240,10 @@ export function createServer(): McpServer {

<!-- prettier-ignore -->
```ts source="../examples/quickstart/main.ts"
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { createMcpExpressApp } from "@modelcontextprotocol/express";
import type { McpServer } from "@modelcontextprotocol/server";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
import cors from "cors";
import type { Request, Response } from "express";
import { createServer } from "./server.js";
Expand All @@ -263,7 +263,7 @@ export async function startStreamableHTTPServer(

app.all("/mcp", async (req: Request, res: Response) => {
const server = createServer();
const transport = new StreamableHTTPServerTransport({
const transport = new NodeStreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});

Expand Down
2 changes: 1 addition & 1 deletion examples/basic-host/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\""
},
"dependencies": {
"@modelcontextprotocol/client": "2.0.0-beta.3",
"@modelcontextprotocol/ext-apps": "^1.7.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"zod": "^4.1.13"
Expand Down
14 changes: 9 additions & 5 deletions examples/basic-host/src/implementation.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { RESOURCE_MIME_TYPE, getToolUiResourceUri, type McpUiSandboxProxyReadyNotification, AppBridge, PostMessageTransport, type McpUiResourceCsp, type McpUiResourcePermissions, buildAllowAttribute, type McpUiUpdateModelContextRequest, type McpUiMessageRequest } from "@modelcontextprotocol/ext-apps/app-bridge";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import type { CallToolResult, Resource, Tool } from "@modelcontextprotocol/sdk/types.js";
import {
Client,
SSEClientTransport,
StreamableHTTPClientTransport,
type CallToolResult,
type Resource,
type Tool,
} from "@modelcontextprotocol/client";
import { getTheme, onThemeChange } from "./theme";
import { HOST_STYLE_VARIABLES } from "./host-styles";

Expand Down Expand Up @@ -94,7 +98,7 @@ export function callTool(
input: Record<string, unknown>,
): ToolCallInfo {
log.info("Calling tool", name, "with input", input);
const resultPromise = serverInfo.client.callTool({ name, arguments: input }) as Promise<CallToolResult>;
const resultPromise = serverInfo.client.callTool({ name, arguments: input });

const tool = serverInfo.tools.get(name);
if (!tool) {
Expand Down
2 changes: 1 addition & 1 deletion examples/basic-host/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getToolUiResourceUri, McpUiToolMetaSchema } from "@modelcontextprotocol/ext-apps/app-bridge";
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
import type { Tool } from "@modelcontextprotocol/client";
import { Component, type ErrorInfo, type ReactNode, StrictMode, Suspense, use, useEffect, useMemo, useRef, useState } from "react";
import { createRoot } from "react-dom/client";
import { callTool, connectToServer, hasAppHtml, initializeApp, loadSandboxProxy, log, newAppBridge, type ServerInfo, type ToolCallInfo, type ModelContext, type AppMessage } from "./implementation";
Expand Down
10 changes: 5 additions & 5 deletions examples/basic-server-preact/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
* Or: node dist/index.js [--stdio]
*/

import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { createMcpExpressApp } from "@modelcontextprotocol/express";
import type { McpServer } from "@modelcontextprotocol/server";
import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
import cors from "cors";
import type { Request, Response } from "express";
import { createServer } from "./server.js";
Expand All @@ -27,7 +27,7 @@ export async function startStreamableHTTPServer(

app.all("/mcp", async (req: Request, res: Response) => {
const server = createServer();
const transport = new StreamableHTTPServerTransport({
const transport = new NodeStreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});

Expand Down
5 changes: 4 additions & 1 deletion examples/basic-server-preact/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
"prepublishOnly": "npm run build"
},
"dependencies": {
"@modelcontextprotocol/client": "2.0.0-beta.3",
"@modelcontextprotocol/express": "2.0.0-beta.3",
"@modelcontextprotocol/ext-apps": "^1.7.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"@modelcontextprotocol/node": "2.0.0-beta.3",
"@modelcontextprotocol/server": "2.0.0-beta.3",
"cors": "^2.8.5",
"express": "^5.1.0",
"preact": "^10.0.0",
Expand Down
4 changes: 2 additions & 2 deletions examples/basic-server-preact/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
import { McpServer } from "@modelcontextprotocol/server";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/server";
import fs from "node:fs/promises";
import path from "node:path";
import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server";
Expand Down
2 changes: 1 addition & 1 deletion examples/basic-server-preact/src/mcp-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
applyHostStyleVariables,
type McpUiHostContext,
} from "@modelcontextprotocol/ext-apps";
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import type { CallToolResult } from "@modelcontextprotocol/client";
import { useCallback, useEffect, useState } from "preact/hooks";
import { render } from "preact";
import styles from "./mcp-app.module.css";
Expand Down
10 changes: 5 additions & 5 deletions examples/basic-server-react/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
* Or: node dist/index.js [--stdio]
*/

import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { createMcpExpressApp } from "@modelcontextprotocol/express";
import type { McpServer } from "@modelcontextprotocol/server";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
import cors from "cors";
import type { Request, Response } from "express";
import { createServer } from "./server.js";
Expand All @@ -27,7 +27,7 @@ export async function startStreamableHTTPServer(

app.all("/mcp", async (req: Request, res: Response) => {
const server = createServer();
const transport = new StreamableHTTPServerTransport({
const transport = new NodeStreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});

Expand Down
4 changes: 3 additions & 1 deletion examples/basic-server-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
"prepublishOnly": "npm run build"
},
"dependencies": {
"@modelcontextprotocol/express": "2.0.0-beta.3",
"@modelcontextprotocol/ext-apps": "^1.7.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"@modelcontextprotocol/node": "2.0.0-beta.3",
"@modelcontextprotocol/server": "2.0.0-beta.3",
"cors": "^2.8.5",
"express": "^5.1.0",
"react": "^19.2.0",
Expand Down
4 changes: 2 additions & 2 deletions examples/basic-server-react/server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
import { McpServer } from "@modelcontextprotocol/server";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/server";
import fs from "node:fs/promises";
import path from "node:path";

Expand Down
10 changes: 5 additions & 5 deletions examples/basic-server-react/src/mcp-app.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/**
* @file App that demonstrates a few features using MCP Apps SDK + React.
*/
import type { App, McpUiHostContext } from "@modelcontextprotocol/ext-apps";
import type { App, CallToolResult, McpUiHostContext } from "@modelcontextprotocol/ext-apps";
import { useApp } from "@modelcontextprotocol/ext-apps/react";
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import { StrictMode, useCallback, useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
import styles from "./mcp-app.module.css";


function extractTime(callToolResult: CallToolResult): string {
const { text } = callToolResult.content?.find((c) => c.type === "text")!;
return text;
const sc = callToolResult.structuredContent as { time?: string } | undefined;
if (sc?.time) return sc.time;
const { text } = callToolResult.content?.find((c) => c.type === "text") ?? {};
return text ?? "";
}


Expand Down
10 changes: 5 additions & 5 deletions examples/basic-server-solid/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
* Or: node dist/index.js [--stdio]
*/

import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { createMcpExpressApp } from "@modelcontextprotocol/express";
import type { McpServer } from "@modelcontextprotocol/server";
import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
import cors from "cors";
import type { Request, Response } from "express";
import { createServer } from "./server.js";
Expand All @@ -27,7 +27,7 @@ export async function startStreamableHTTPServer(

app.all("/mcp", async (req: Request, res: Response) => {
const server = createServer();
const transport = new StreamableHTTPServerTransport({
const transport = new NodeStreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});

Expand Down
5 changes: 4 additions & 1 deletion examples/basic-server-solid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
"prepublishOnly": "npm run build"
},
"dependencies": {
"@modelcontextprotocol/client": "2.0.0-beta.3",
"@modelcontextprotocol/express": "2.0.0-beta.3",
"@modelcontextprotocol/ext-apps": "^1.7.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"@modelcontextprotocol/node": "2.0.0-beta.3",
"@modelcontextprotocol/server": "2.0.0-beta.3",
"cors": "^2.8.5",
"express": "^5.1.0",
"solid-js": "1.9.10",
Expand Down
4 changes: 2 additions & 2 deletions examples/basic-server-solid/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
import { McpServer } from "@modelcontextprotocol/server";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/server";
import fs from "node:fs/promises";
import path from "node:path";
import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server";
Expand Down
2 changes: 1 addition & 1 deletion examples/basic-server-solid/src/mcp-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
applyHostStyleVariables,
type McpUiHostContext,
} from "@modelcontextprotocol/ext-apps";
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import type { CallToolResult } from "@modelcontextprotocol/client";
import { createEffect, createSignal, onMount, Show } from "solid-js";
import { render } from "solid-js/web";
import styles from "./mcp-app.module.css";
Expand Down
10 changes: 5 additions & 5 deletions examples/basic-server-svelte/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
* Or: node dist/index.js [--stdio]
*/

import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { createMcpExpressApp } from "@modelcontextprotocol/express";
import type { McpServer } from "@modelcontextprotocol/server";
import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
import cors from "cors";
import type { Request, Response } from "express";
import { createServer } from "./server.js";
Expand All @@ -27,7 +27,7 @@ export async function startStreamableHTTPServer(

app.all("/mcp", async (req: Request, res: Response) => {
const server = createServer();
const transport = new StreamableHTTPServerTransport({
const transport = new NodeStreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});

Expand Down
5 changes: 4 additions & 1 deletion examples/basic-server-svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
"prepublishOnly": "npm run build"
},
"dependencies": {
"@modelcontextprotocol/client": "2.0.0-beta.3",
"@modelcontextprotocol/express": "2.0.0-beta.3",
"@modelcontextprotocol/ext-apps": "^1.7.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"@modelcontextprotocol/node": "2.0.0-beta.3",
"@modelcontextprotocol/server": "2.0.0-beta.3",
"cors": "^2.8.5",
"express": "^5.1.0",
"svelte": "^5.0.0",
Expand Down
4 changes: 2 additions & 2 deletions examples/basic-server-svelte/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
import { McpServer } from "@modelcontextprotocol/server";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/server";
import fs from "node:fs/promises";
import path from "node:path";
import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server";
Expand Down
2 changes: 1 addition & 1 deletion examples/basic-server-svelte/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
applyHostStyleVariables,
type McpUiHostContext,
} from "@modelcontextprotocol/ext-apps";
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import type { CallToolResult } from "@modelcontextprotocol/client";

function extractTime(result: CallToolResult): string {
const { text } = result.content?.find((c) => c.type === "text")!;
Expand Down
Loading