refactor: finish MCP SDK v2 migration
This commit is contained in:
parent
a76e3a7691
commit
f94cb38b0b
112 changed files with 684 additions and 540 deletions
|
|
@ -60,8 +60,8 @@ rm -fR package-lock.json node_modules && \
|
|||
|
||||
### Key Source Files
|
||||
|
||||
- `src/app.ts` - `App` class extends MCP Protocol, handles guest initialization, tool calls, messaging
|
||||
- `src/app-bridge.ts` - `AppBridge` class for hosts, proxies MCP requests, sends tool input/results to guests
|
||||
- `src/app.ts` - `App` subclasses the base MCP SDK `Client`, handles View initialization, tool calls, and messaging
|
||||
- `src/app-bridge.ts` - `AppBridge` subclasses the base MCP SDK `Server` for the inner iframe channel and proxies through a separate outer `Client`
|
||||
- `src/server/index.ts` - Helpers for MCP servers to register tools/resources with UI metadata
|
||||
- `src/types.ts` - Protocol types re-exported from `spec.types.ts` and Zod schemas from `generated/schema.ts` (auto-generated during build)
|
||||
- `src/message-transport.ts` - `PostMessageTransport` for iframe communication
|
||||
|
|
@ -70,12 +70,12 @@ rm -fR package-lock.json node_modules && \
|
|||
### Protocol Flow
|
||||
|
||||
```
|
||||
View (App) <--PostMessageTransport--> Host (AppBridge) <--MCP Client--> MCP Server
|
||||
View (App/Client) <--PostMessageTransport--> Host (AppBridge/Server) <--separate MCP Client--> MCP Server
|
||||
```
|
||||
|
||||
1. Host creates iframe with view HTML
|
||||
2. View creates `App` instance and calls `connect()` with `PostMessageTransport`
|
||||
3. View sends `ui/initialize` request, receives host capabilities and context
|
||||
3. View and Host complete the temporary inner base MCP handshake, then the View sends `ui/initialize` and receives authoritative Apps capabilities and context
|
||||
4. Host sends `sendToolInput()` with tool arguments after initialization
|
||||
5. View can call server tools via `app.callServerTool()` or send messages via `app.sendMessage()`
|
||||
6. Host sends `sendToolResult()` when tool execution completes
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -122,9 +122,17 @@ resources:
|
|||
## Getting Started
|
||||
|
||||
```bash
|
||||
npm install -S @modelcontextprotocol/ext-apps
|
||||
npm install -S @modelcontextprotocol/ext-apps \
|
||||
@modelcontextprotocol/client@2.0.0-beta.4 \
|
||||
@modelcontextprotocol/server@2.0.0-beta.4 \
|
||||
@modelcontextprotocol/core@2.0.0-beta.4 \
|
||||
zod@^4.2.0
|
||||
```
|
||||
|
||||
This release uses the split base MCP SDK v2 packages. Install all three at the
|
||||
exact published beta.4 version so the Apps SDK and your MCP client/server share
|
||||
one compatible protocol implementation.
|
||||
|
||||
**New here?** Start with the
|
||||
[Quickstart Guide](https://apps.extensions.modelcontextprotocol.io/api/documents/Quickstart.html)
|
||||
to build your first MCP App.
|
||||
|
|
|
|||
12
build.bun.ts
12
build.bun.ts
|
|
@ -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 dependencies stay external in the standard entry points so consumers
|
||||
// share one base MCP SDK and Zod instance. The *-with-deps entry points keep
|
||||
// bundling these dependencies for standalone browser use.
|
||||
const PEER_EXTERNALS = [
|
||||
"@modelcontextprotocol/client",
|
||||
"@modelcontextprotocol/core",
|
||||
"@modelcontextprotocol/server",
|
||||
"zod",
|
||||
];
|
||||
|
||||
await Promise.all([
|
||||
buildJs("src/app.ts", {
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ registerAppTool(
|
|||
"get_account_balance",
|
||||
{
|
||||
description: "Get account balance",
|
||||
inputSchema: { accountId: z.string() },
|
||||
inputSchema: z.object({ accountId: z.string() }),
|
||||
},
|
||||
async ({ accountId }) => {
|
||||
if (!authInfo) {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
@ -78,7 +78,7 @@ function createServer() {
|
|||
{
|
||||
title: "Shopping Cart",
|
||||
description: "Display the user's shopping cart",
|
||||
inputSchema: { userId: z.string() },
|
||||
inputSchema: z.object({ userId: z.string() }),
|
||||
annotations: { readOnlyHint: true },
|
||||
_meta: {
|
||||
"openai/outputTemplate": "ui://view/cart.html",
|
||||
|
|
@ -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,
|
||||
|
|
@ -144,7 +144,7 @@ function createServer() {
|
|||
{
|
||||
title: "Shopping Cart",
|
||||
description: "Display the user's shopping cart",
|
||||
inputSchema: { userId: z.string() },
|
||||
inputSchema: z.object({ userId: z.string() }),
|
||||
annotations: { readOnlyHint: true },
|
||||
_meta: { ui: { resourceUri: "ui://view/cart.html" } },
|
||||
},
|
||||
|
|
|
|||
|
|
@ -56,7 +56,11 @@ flowchart LR
|
|||
- **Host** — The chat client (e.g., Claude Desktop) that connects to servers, embeds Views in iframes, and proxies communication between them.
|
||||
- **View** — The UI running inside a sandboxed iframe. It receives tool data from the Host and can call server tools or send messages back to the chat.
|
||||
|
||||
The View acts as an MCP client, the Host acts as a proxy, and the Server is a standard MCP server.
|
||||
The View's `App` subclasses the base MCP SDK `Client`. The Host's `AppBridge`
|
||||
subclasses the base MCP SDK `Server` for the inner iframe channel, while a
|
||||
separate outer `Client` connects the Host to the actual MCP Server. Keeping
|
||||
those two connections separate prevents iframe negotiation and capabilities
|
||||
from leaking into the server connection.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
|
|
@ -93,7 +97,7 @@ sequenceDiagram
|
|||
```
|
||||
|
||||
1. **Discovery** — The Host learns about tools and their UI resources when connecting to the server.
|
||||
2. **Initialization** — When a UI tool is called, the Host renders the iframe. The View sends `ui/initialize` and receives host context (theme, capabilities, container dimensions). This handshake ensures the View is ready before receiving data.
|
||||
2. **Initialization** — When a UI tool is called, the Host renders the iframe. The SDK first completes its temporary inner base MCP handshake, then the View sends `ui/initialize` and receives host context (theme, capabilities, container dimensions). `ui/initialize` remains authoritative for Apps capabilities and identity, and `ui/notifications/initialized` remains the public View-ready signal.
|
||||
3. **Data delivery** — The Host sends tool arguments and, once available, tool results to the View. Results include both `content` (text for the model's context) and optionally `structuredContent` (data optimized for UI rendering). This separation lets servers provide rich data to the UI without bloating the model's context.
|
||||
4. **Interactive phase** — The user interacts with the View. The View can call tools, send messages, or update context.
|
||||
5. **Teardown** — Before unmounting, the Host notifies the View so it can save state or release resources.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ registerAppTool(
|
|||
"update-quantity",
|
||||
{
|
||||
description: "Update item quantity in cart",
|
||||
inputSchema: { itemId: z.string(), quantity: z.number() },
|
||||
inputSchema: z.object({ itemId: z.string(), quantity: z.number() }),
|
||||
_meta: {
|
||||
ui: {
|
||||
resourceUri: "ui://shop/cart.html",
|
||||
|
|
@ -127,14 +127,14 @@ registerAppTool(
|
|||
{
|
||||
title: "Read Data Bytes",
|
||||
description: "Load binary data in chunks",
|
||||
inputSchema: {
|
||||
inputSchema: z.object({
|
||||
id: z.string().describe("Resource identifier"),
|
||||
offset: z.number().min(0).default(0).describe("Byte offset"),
|
||||
byteCount: z
|
||||
.number()
|
||||
.default(MAX_CHUNK_BYTES)
|
||||
.describe("Bytes to read"),
|
||||
},
|
||||
}),
|
||||
outputSchema: DataChunkSchema,
|
||||
// Hidden from model - only callable by the App
|
||||
_meta: { ui: { visibility: ["app"] } },
|
||||
|
|
@ -281,10 +281,7 @@ server.registerResource(
|
|||
|
||||
<!-- prettier-ignore -->
|
||||
```ts source="./patterns.tsx#binaryBlobResourceClient"
|
||||
const result = await app.request(
|
||||
{ method: "resources/read", params: { uri: `video://${videoId}` } },
|
||||
ReadResourceResultSchema,
|
||||
);
|
||||
const result = await app.readServerResource({ uri: `video://${videoId}` });
|
||||
|
||||
const content = result.contents[0];
|
||||
if (!content || !("blob" in content)) {
|
||||
|
|
|
|||
|
|
@ -17,16 +17,12 @@ 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 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";
|
||||
|
||||
/**
|
||||
|
|
@ -117,14 +113,14 @@ function chunkedDataServer(server: McpServer) {
|
|||
{
|
||||
title: "Read Data Bytes",
|
||||
description: "Load binary data in chunks",
|
||||
inputSchema: {
|
||||
inputSchema: z.object({
|
||||
id: z.string().describe("Resource identifier"),
|
||||
offset: z.number().min(0).default(0).describe("Byte offset"),
|
||||
byteCount: z
|
||||
.number()
|
||||
.default(MAX_CHUNK_BYTES)
|
||||
.describe("Bytes to read"),
|
||||
},
|
||||
}),
|
||||
outputSchema: DataChunkSchema,
|
||||
// Hidden from model - only callable by the App
|
||||
_meta: { ui: { visibility: ["app"] } },
|
||||
|
|
@ -252,10 +248,7 @@ function binaryBlobResourceServer(
|
|||
*/
|
||||
async function binaryBlobResourceClient(app: App, videoId: string) {
|
||||
//#region binaryBlobResourceClient
|
||||
const result = await app.request(
|
||||
{ method: "resources/read", params: { uri: `video://${videoId}` } },
|
||||
ReadResourceResultSchema,
|
||||
);
|
||||
const result = await app.readServerResource({ uri: `video://${videoId}` });
|
||||
|
||||
const content = result.contents[0];
|
||||
if (!content || !("blob" in content)) {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ This tutorial assumes you've built an MCP server before and are comfortable with
|
|||
|
||||
We'll use the [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) to build the server.
|
||||
|
||||
You'll also need Node.js 18+.
|
||||
You'll also need Node.js 20+.
|
||||
|
||||
## 1. Set up the project
|
||||
|
||||
|
|
@ -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/client@2.0.0-beta.4 @modelcontextprotocol/core@2.0.0-beta.4 @modelcontextprotocol/server@2.0.0-beta.4 @modelcontextprotocol/node@2.0.0-beta.4 @modelcontextprotocol/express@2.0.0-beta.4 zod@^4.2.0 express cors
|
||||
npm install -D typescript vite vite-plugin-singlefile @types/express @types/cors @types/node tsx concurrently cross-env
|
||||
```
|
||||
|
||||
|
|
@ -178,9 +178,10 @@ 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";
|
||||
import { z } from "zod";
|
||||
|
||||
const DIST_DIR = path.join(import.meta.dirname, "dist");
|
||||
|
||||
|
|
@ -205,7 +206,7 @@ export function createServer(): McpServer {
|
|||
{
|
||||
title: "Get Time",
|
||||
description: "Returns the current server time.",
|
||||
inputSchema: {},
|
||||
inputSchema: z.object({}),
|
||||
_meta: { ui: { resourceUri } }, // Links this tool to its UI resource
|
||||
},
|
||||
async () => {
|
||||
|
|
@ -240,10 +241,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 { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
|
||||
import type { McpServer } from "@modelcontextprotocol/server";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
||||
import cors from "cors";
|
||||
import type { Request, Response } from "express";
|
||||
import { createServer } from "./server.js";
|
||||
|
|
@ -263,7 +264,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,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ The [`basic-host`](https://github.com/modelcontextprotocol/ext-apps/tree/main/ex
|
|||
cd examples/basic-host
|
||||
```
|
||||
|
||||
The root install runs the package build, including type-checking the
|
||||
documentation snippets against the exact base MCP SDK beta.4 packages. Do
|
||||
not bypass a failed build before testing the host.
|
||||
|
||||
2. Start basic-host, pointing it to your MCP server:
|
||||
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/ext-apps": "^1.7.0",
|
||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||
"@modelcontextprotocol/client": "2.0.0-beta.4",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"zod": "^4.1.13"
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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 { createMcpExpressApp } from "@modelcontextprotocol/express";
|
||||
import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
|
||||
import type { McpServer } from "@modelcontextprotocol/server";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
||||
import cors from "cors";
|
||||
import type { Request, Response } from "express";
|
||||
import { createServer } from "./server.js";
|
||||
|
|
@ -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,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@
|
|||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/client": "2.0.0-beta.4",
|
||||
"@modelcontextprotocol/ext-apps": "^1.7.0",
|
||||
"@modelcontextprotocol/express": "2.0.0-beta.4",
|
||||
"@modelcontextprotocol/node": "2.0.0-beta.4",
|
||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||
"@modelcontextprotocol/server": "2.0.0-beta.4",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^5.1.0",
|
||||
"preact": "^10.0.0",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
|
||||
import {
|
||||
McpServer,
|
||||
type CallToolResult,
|
||||
type 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";
|
||||
import { z } from "zod";
|
||||
// Works both from source (server.ts) and compiled (dist/server.js)
|
||||
const DIST_DIR = import.meta.filename.endsWith(".ts")
|
||||
? path.join(import.meta.dirname, "dist")
|
||||
|
|
@ -28,7 +32,7 @@ export function createServer(): McpServer {
|
|||
{
|
||||
title: "Get Time",
|
||||
description: "Returns the current server time as an ISO 8601 string.",
|
||||
inputSchema: {},
|
||||
inputSchema: z.object({}),
|
||||
_meta: { ui: { resourceUri } }, // Links this tool to its UI resource
|
||||
},
|
||||
async (): Promise<CallToolResult> => {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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 { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
|
||||
import type { McpServer } from "@modelcontextprotocol/server";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
||||
import cors from "cors";
|
||||
import type { Request, Response } from "express";
|
||||
import { createServer } from "./server.js";
|
||||
|
|
@ -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,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -34,10 +34,11 @@
|
|||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/client": "2.0.0-beta.4",
|
||||
"@modelcontextprotocol/ext-apps": "^1.7.0",
|
||||
"@modelcontextprotocol/express": "2.0.0-beta.4",
|
||||
"@modelcontextprotocol/node": "2.0.0-beta.4",
|
||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||
"@modelcontextprotocol/server": "2.0.0-beta.4",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^5.1.0",
|
||||
"react": "^19.2.0",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
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,
|
||||
type CallToolResult,
|
||||
type ReadResourceResult,
|
||||
} from "@modelcontextprotocol/server";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { z } from "zod";
|
||||
|
||||
// Works both from source (server.ts) and compiled (dist/server.js)
|
||||
const DIST_DIR = import.meta.filename.endsWith(".ts")
|
||||
|
|
@ -29,7 +33,7 @@ export function createServer(): McpServer {
|
|||
{
|
||||
title: "Get Time",
|
||||
description: "Returns the current server time as an ISO 8601 string.",
|
||||
inputSchema: {},
|
||||
inputSchema: z.object({}),
|
||||
_meta: { ui: { resourceUri } }, // Links this tool to its UI resource
|
||||
},
|
||||
async (): Promise<CallToolResult> => {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue