From 6050ccf2afc02b3a9ec6b08423991751d397075c Mon Sep 17 00:00:00 2001 From: Andrew Harvard Date: Tue, 3 Jun 2025 13:37:12 -0400 Subject: [PATCH 1/3] fix typescript types to be compatible with MCP SDK --- packages/server/src/index.ts | 41 ++++++++++++++++++++++-------------- packages/server/src/types.ts | 22 ++++++++++++++++++- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index b69eb0b1..566c1272 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -4,17 +4,17 @@ */ // Import types first -import { CreateHtmlResourceOptions } from './types.js'; +import { + Base64BlobContent, + CreateHtmlResourceOptions, + HtmlTextContent, + mimeType, +} from './types.js'; -export interface HtmlResourceBlock { +export type HtmlResourceBlock = { type: 'resource'; - resource: { - uri: string; // Primary identifier. Starts with "ui://" - mimeType: 'text/html' | 'text/uri-list'; // text/html for rawHtml content, text/uri-list for externalUrl content - text?: string; // HTML content (for mimeType `text/html`), or iframe URL (for mimeType `text/uri-list`) - blob?: string; // Base64 encoded HTML content (for mimeType `text/html`), or iframe URL (for mimeType `text/uri-list`) - }; -} + resource: HtmlTextContent | Base64BlobContent; +}; /** * Robustly encodes a UTF-8 string to Base64. @@ -60,7 +60,7 @@ export function createHtmlResource( options: CreateHtmlResourceOptions, ): HtmlResourceBlock { let actualContentString: string; - let mimeType: 'text/html' | 'text/uri-list'; + let mimeType: mimeType; if (options.content.type === 'rawHtml') { if (!options.uri.startsWith('ui://')) { @@ -96,18 +96,27 @@ export function createHtmlResource( ); } - const resource: HtmlResourceBlock['resource'] = { - uri: options.uri, - mimeType: mimeType, - }; + let resource: HtmlResourceBlock['resource']; switch (options.delivery) { case 'text': - resource.text = actualContentString; + resource = { + uri: options.uri, + mimeType: mimeType, + text: actualContentString, + }; break; case 'blob': - resource.blob = robustUtf8ToBase64(actualContentString); + resource = { + uri: options.uri, + mimeType: mimeType, + blob: robustUtf8ToBase64(actualContentString), + }; break; + default: + // Exhaustive check + const exhaustiveCheck: never = options.delivery; + throw new Error(`Invalid delivery type: ${exhaustiveCheck}`); } return { diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts index 893f216c..a796e811 100644 --- a/packages/server/src/types.ts +++ b/packages/server/src/types.ts @@ -1,9 +1,29 @@ +// Primary identifier for the resource. Starts with ui://` +export type URI = `ui://${string}`; + +// text/html for rawHtml content, text/uri-list for externalUrl content +export type mimeType = 'text/html' | 'text/uri-list'; + +export type HtmlTextContent = { + uri: URI; + mimeType: mimeType; + text: string; // HTML content (for mimeType `text/html`), or iframe URL (for mimeType `text/uri-list`) + blob?: never; +}; + +export type Base64BlobContent = { + uri: URI; + mimeType: mimeType; + blob: string; // Base64 encoded HTML content (for mimeType `text/html`), or iframe URL (for mimeType `text/uri-list`) + text?: never; +}; + export type ResourceContentPayload = | { type: 'rawHtml'; htmlString: string } | { type: 'externalUrl'; iframeUrl: string }; export interface CreateHtmlResourceOptions { - uri: string; // REQUIRED. Must start with "ui://" if content.type is "rawHtml", + uri: URI; // REQUIRED. Must start with "ui://" if content.type is "rawHtml", // or "ui-app://" if content.type is "externalUrl". content: ResourceContentPayload; // REQUIRED. The actual content payload. delivery: 'text' | 'blob'; // REQUIRED. How the content string (htmlString or iframeUrl) should be packaged. From 3e9824a51627927da116d449f6293325e59e1c00 Mon Sep 17 00:00:00 2001 From: Andrew Harvard Date: Tue, 3 Jun 2025 13:56:51 -0400 Subject: [PATCH 2/3] update mimeType to MimeType --- packages/server/src/index.ts | 14 ++++++-------- packages/server/src/types.ts | 13 +++++++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 359e126a..26434af6 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -8,13 +8,13 @@ import { Base64BlobContent, CreateHtmlResourceOptions, HtmlTextContent, - mimeType, + MimeType, UiActionResult, UiActionResultLink, UiActionResultNotification, UiActionResultPrompt, UiActionResultIntent, - UiActionResultToolCall + UiActionResultToolCall, } from './types.js'; export type HtmlResourceBlock = { @@ -66,7 +66,7 @@ export function createHtmlResource( options: CreateHtmlResourceOptions, ): HtmlResourceBlock { let actualContentString: string; - let mimeType: mimeType; + let mimeType: MimeType; if (options.content.type === 'rawHtml') { if (!options.uri.startsWith('ui://')) { @@ -173,9 +173,7 @@ export function uiActionResultToolCall( }; } -export function uiActionResultPrompt( - prompt: string, -): UiActionResultPrompt { +export function uiActionResultPrompt(prompt: string): UiActionResultPrompt { return { type: 'prompt', payload: { @@ -209,10 +207,10 @@ export function uiActionResultIntent( export function uiActionResultNotification( message: string, ): UiActionResultNotification { - return { + return { type: 'notification', payload: { message, }, }; -} \ No newline at end of file +} diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts index 2e7adad1..b921e6ad 100644 --- a/packages/server/src/types.ts +++ b/packages/server/src/types.ts @@ -2,18 +2,18 @@ export type URI = `ui://${string}`; // text/html for rawHtml content, text/uri-list for externalUrl content -export type mimeType = 'text/html' | 'text/uri-list'; +export type MimeType = 'text/html' | 'text/uri-list'; export type HtmlTextContent = { uri: URI; - mimeType: mimeType; + mimeType: MimeType; text: string; // HTML content (for mimeType `text/html`), or iframe URL (for mimeType `text/uri-list`) blob?: never; }; export type Base64BlobContent = { uri: URI; - mimeType: mimeType; + mimeType: MimeType; blob: string; // Base64 encoded HTML content (for mimeType `text/html`), or iframe URL (for mimeType `text/uri-list`) text?: never; }; @@ -29,7 +29,12 @@ export interface CreateHtmlResourceOptions { delivery: 'text' | 'blob'; // REQUIRED. How the content string (htmlString or iframeUrl) should be packaged. } -export type UiActionType = 'tool' | 'prompt' | 'link' | 'intent' | 'notification'; +export type UiActionType = + | 'tool' + | 'prompt' + | 'link' + | 'intent' + | 'notification'; export type UiActionResultToolCall = { type: 'tool'; From 0ad7fddee8f4918f3c91c31d121699b951aef480 Mon Sep 17 00:00:00 2001 From: Andrew Harvard Date: Mon, 9 Jun 2025 08:20:29 -0400 Subject: [PATCH 3/3] fix lint unexpected lexical declaration lint error --- packages/server/src/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 26434af6..d4f5897d 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -121,8 +121,10 @@ export function createHtmlResource( break; default: // Exhaustive check - const exhaustiveCheck: never = options.delivery; - throw new Error(`Invalid delivery type: ${exhaustiveCheck}`); + (() => { + const exhaustiveCheck: never = options.delivery; + throw new Error(`Invalid delivery type: ${exhaustiveCheck}`); + })(); } return {