-
Notifications
You must be signed in to change notification settings - Fork 2
B-MCP: An Idea for an in browser implementation of the Model-Context-Protocol #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThis update migrates the project from a Next.js-based React application to a Vite-powered React app with Cloudflare Workers integration. All Next.js-specific files, configuration, and API routes are removed, including layout, page, and assistant components. In their place, Vite configuration, an HTML entry point, and a new React app structure are introduced. The package dependencies are overhauled to support Vite, Tailwind CSS, Cloudflare Workers, and an MCP-Window protocol implementation. New TypeScript modules define and implement the MCP-Window protocol, including provider and client SDKs, type definitions, and React integration hooks. The project now uses modular TypeScript configuration files for app, node, and worker environments, and is configured for deployment with Cloudflare Wrangler. The README is rewritten to document the MCP-Window protocol and its usage. Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. Note ⚡️ Faster reviews with cachingCodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 28
🔭 Outside diff range comments (1)
src/components/assistant-ui/tool-fallback.tsx (1)
20-22
:⚠️ Potential issueInvert collapse toggle icons
The current logic shows an "up" icon when collapsed; it should show "down" to indicate expansion. Swap the icons:- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />} + {isCollapsed ? <ChevronDownIcon /> : <ChevronUpIcon />}
🧹 Nitpick comments (33)
src/index.css (1)
1-1
: Ensure Tailwind CSS directives are included
Importing@import "tailwindcss";
alone may not apply the required utility classes. Typically, your global CSS should include the Tailwind directives:@tailwind base; @tailwind components; @tailwind utilities;Alternatively, confirm that your Vite Tailwind plugin injects these automatically.
src/components/assistant-ui/tool-fallback.tsx (1)
15-15
: Fix invalid Tailwind class for icon sizing
Thelucide-react
icons requireh-4 w-4
rather thansize-4
. Update to:- <CheckIcon className="size-4" /> + <CheckIcon className="h-4 w-4" />index.html (2)
7-7
: Update the page title to reflect your application.The current title "Vite + React + TS" is the default from Vite templates. Consider updating it to something specific to your MCP application, such as "MCP Browser Demo" or similar.
- <title>Vite + React + TS</title> + <title>Model-Context-Protocol Browser Demo</title>
5-5
: Consider updating the favicon.The current favicon references the default Vite SVG. Consider replacing it with your own favicon that represents your application.
- <link rel="icon" type="image/svg+xml" href="/vite.svg" /> + <link rel="icon" type="image/svg+xml" href="/your-app-icon.svg" />vite.config.ts (1)
1-17
: Well-structured Vite configuration.The Vite configuration looks good with appropriate plugins for React, Tailwind CSS, and Cloudflare. The path alias setup for "@" will make imports cleaner and more maintainable.
Consider adding environment-specific configurations if you have different needs for development and production:
export default defineConfig(({ mode }) => { const isDev = mode === 'development'; return { plugins: [react(), tailwindcss(), cloudflare()], resolve: { alias: { "@": path.resolve(__dirname, "./src"), }, }, // Environment-specific settings build: { sourcemap: isDev, // Add other environment-specific build options } }; });src/components/app-sidebar.tsx (1)
37-41
: Inconsistent blank line spacingThere are several inconsistent blank lines throughout the file (lines 37, 41, 54). Consider standardizing the spacing pattern for better readability.
</SidebarContent> - <SidebarRail /> <SidebarFooter> <SidebarMenu> - <SidebarMenuItem>tsconfig.node.json (1)
30-30
: Confirm vite.config.ts is the only file that needs Node.js configThe configuration only includes
vite.config.ts
. If you have other Node.js-specific files (like build scripts or ESLint config), consider including them as well.🧰 Tools
🪛 Biome (1.9.4)
[error] 30-30: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 30-30: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 30-30: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 30-31: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
worker/index.ts (1)
23-25
: Remove unnecessary empty linesThere are multiple consecutive empty lines that should be cleaned up.
if (c.env.NODE_ENV === 'development') { console.log(JSON.stringify({tools, frontendTools:frontendTools(tools) },null, 2)) } - - - const result = streamText({tsconfig.json (1)
18-19
: Remove empty line in compilerOptions objectThere's an unnecessary empty line that should be removed.
"compilerOptions": { "types": [ "./worker-configuration.d.ts" ], - }
tsconfig.app.json (1)
13-32
: Consider adding comments explaining non-standard settingsSome of the configuration options like
verbatimModuleSyntax
andmoduleDetection: "force"
might not be familiar to all developers. Consider adding comments explaining their purpose./* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, + /* Preserves import statements exactly as written */ "verbatimModuleSyntax": true, + /* Ensures all files are treated as modules */ "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx",🧰 Tools
🪛 Biome (1.9.4)
[error] 13-13: JSON standard does not allow comments.
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: JSON standard does not allow comments.
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 28-28: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 28-28: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 28-32: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
src/Assistant.tsx (1)
19-21
: Remove or implement the unused button.This button has an empty onClick handler and doesn't seem to serve any purpose in the UI.
Either remove the button or implement its functionality:
- <Button onClick={() => { - - }}>Hello </Button>README.md (4)
190-190
: Remove this placeholder comment before finalizing the README.This note appears to be a reminder for development and should be removed before the final release.
-This README provides a good overview for someone wanting to understand or implement this in-window MCP variant. Remember to replace placeholders (like links to type definitions or SDK repositories) if you formalize this into actual files.
79-79
: Fix the API Interface heading to remove redundancy.The phrase "API Interface" is redundant as "API" already stands for "Application Programming Interface".
-## API Interface (`WindowMcpApi`) +## API (`WindowMcpApi`)🧰 Tools
🪛 LanguageTool
[style] ~79-~79: This phrase is redundant (‘I’ stands for ‘Interface’). Use simply “APIInterface”.
Context: ...re-list tools, re-read a resource). ## API Interface (WindowMcpApi
) Thewindow.mcp
obje...(ACRONYM_TAUTOLOGY)
161-161
: Correct the "vice versa" spelling.The expression "vice versa" should be written without a hyphen.
-Trust Model: MCP-Window typically operates within a same-origin or trusted-iframe context. The web page exposing window.mcp is implicitly trusted by the LLM client (or vice-versa, depending on how the components are loaded). +Trust Model: MCP-Window typically operates within a same-origin or trusted-iframe context. The web page exposing window.mcp is implicitly trusted by the LLM client (or vice versa, depending on how the components are loaded).🧰 Tools
🪛 LanguageTool
[grammar] ~161-~161: The expression “vice versa” is spelled without hyphens.
Context: ...mplicitly trusted by the LLM client (or vice-versa, depending on how the components are lo...(VICE_VERSA)
83-101
: The API interface definition is clear and helpful.The TypeScript interface definition provides a good reference for implementers. Consider expanding the type definitions or linking directly to the implementation file.
Add a link to the actual implementation file:
(Refer to mcp-window-types.ts for detailed type definitions) +For the complete implementation, see [mcp-window-types.ts](./src/window.MCP/mcp-window-types.ts).
src/winodw.MCP/mcp-tool-adapter.ts (3)
9-43
: Enhance the schema conversion for better type coverage.The
mcpSchemaToZod
function currently only handles basic types. Consider expanding it to support more complex types like arrays, objects, and enums.case 'boolean': fieldSchema = z.boolean(); break; // Add more types like array, object, enum as needed + case 'array': + if (prop.items) { + // Recursively handle array items + const itemSchema = prop.items.type === 'object' + ? mcpSchemaToZod(prop.items) + : z.any(); // Or handle primitive item types + fieldSchema = z.array(itemSchema); + } else { + fieldSchema = z.array(z.any()); + } + break; + case 'integer': + fieldSchema = z.number().int(); + break; + case 'null': + fieldSchema = z.null(); + break;
59-67
: Improve error handling for tool execution.The current error handling concatenates all error text, but could be enhanced to provide more structured error information.
if (result.isError) { // Assistant UI might expect errors to be thrown or a specific error format // For now, let's return the error content as a string. const errorText = result.content .filter(c => c.type === 'text' && c.text) .map(c => c.text) .join('\n'); - throw new Error(errorText || `MCP tool '${mcpTool.name}' reported an error.`); + const error = new Error(errorText || `MCP tool '${mcpTool.name}' reported an error.`); + // Add additional context to the error object + (error as any).mcpToolName = mcpTool.name; + (error as any).mcpToolError = true; + (error as any).rawContent = result.content; + throw error; }
46-56
: Consider adding validation for the MCP tool schema.The function assumes the MCP tool will have a valid schema, but additional validation could prevent runtime errors.
export function convertMcpToolToAssistantTool( mcpTool: McpTool, mcpClient: McpWindowClient // Pass the client to make the call ) { + // Validate mcpTool has required properties + if (!mcpTool.name) { + throw new Error('MCP tool must have a name'); + } + const zodParams = mcpSchemaToZod(mcpTool.inputSchema); return assistantToolHelper({ name: mcpTool.name, // Assistant UI expects name directly on the tool object description: mcpTool.description, parameters: zodParams,src/main.tsx (4)
3-4
: Duplicate global style imports may bloat bundleBoth
./globals.css
and./index.css
are pulled in at start-up. If they each Tailwind-reset or contain overlapping rules you’ll pay twice in download & parse time, and risk order-dependent side-effects. Prefer a single root stylesheet (or import one from the other) to keep CSS deterministic.
15-19
: Missingdescription
field on resourceMCP
Resource
accepts an optionaldescription
. Supplying one makes the context far more helpful to the model:- { uri: "page://title", name: "Page Title", mimeType: "text/plain" }, + { uri: "page://title", + name: "Page Title", + description: "The current document.title of the page.", + mimeType: "text/plain" },
21-28
: Comment and implementation divergeThe comment says “tool to change the background color” but the tool actually triggers an alert. Either update the comment or the tool implementation to avoid confusion for maintainers and for the model’s self-documentation.
30-36
: Blockingalert()
hurts UX; prefer non-blocking UI
alert()
pauses the JS thread and can feel jarring. Consider a non-blocking toast/snackbar component instead, or at least wrap the call insetTimeout
to avoid stalling React renders. Example:- alert(args.message); + setTimeout(() => window.alert(args.message), 0); // minimal impactBetter would be a dedicated UI component.
src/winodw.MCP/useMcpContextProvider.tsx (3)
1-4
: Remove unused imports to avoid dead-code warnings
tool
,makeAssistantTool
, andz
are imported but never used (the onlyz
usage is already imported on line 4). Drop them or use them; otherwise tsc/ESLint will complain and tree-shaking will carry the cost.
17-19
: Avoid broadany
; leverage generics for type safety
parameters: any
andexecute: (args: any)
throw away the strong typing you already get from Zod. Consider:interface AssistantTool<Params extends z.ZodTypeAny> { name: string; description?: string; parameters: Params; execute: (args: z.infer<Params>) => Promise<any>; }This will surface schema/implementation mismatches at compile time.
163-164
: Remove leftover console.log before shippingDebug logs inside the model-context provider will spam user consoles.
src/winodw.MCP/ClientSDK.ts (3)
1-1
: File header name mismatchThe comment says
mcp-window-client.ts
but the file isClientSDK.ts
; keep them aligned to avoid confusion when grepping.
21-26
: Constructor throws if provider is late-loaded – add retry or async connectMany pages load scripts lazily. Failing immediately makes the client unusable. Consider deferring the lookup to
connect()
or retrying a few times before giving up:- if (!(window as any)[namespace]) { - throw new Error(`MCP Provider not found on window.${namespace}`); - } - this.provider = (window as any)[namespace] as WindowMcpApi; + const prov = (window as any)[namespace] as WindowMcpApi | undefined; + if (!prov) { + throw new Error(`MCP Provider not found on window.${namespace}. Call connect() after provider initialises.`); + } + this.provider = prov;
68-77
: Event listener leaks on multiple clients
onNotification
attaches directly to the provider but never checks for duplicate listeners; creating many clients can leak. Keep a Set of handlers or expose adispose()
to remove all listeners in one go.src/winodw.MCP/serverSDK.ts (3)
24-27
: Useless constructor – delete for cleaner codeThe constructor neither adds logic nor alters initialisation;
super()
is injected automatically.
Removing it silences the BiomenoUselessConstructor
lint error and trims a few bytes.- constructor() { - super(); - } +🧰 Tools
🪛 Biome (1.9.4)
[error] 25-27: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
44-45
: Generics wrongly referenceZodTypeDef
without import and create very long Map value typesBesides the missing import, embedding the complete generic signature in the
Map
value
makes the line hard to read. Consider extracting helper interfaces:interface ToolEntry extends Tool { handler: ToolHandler; inputValidator?: ZodSchema<any, ZodTypeDef, any>; } private tools = new Map<string, ToolEntry>();Readability & DX both improve.
212-215
: Global export without collision safetyBlindly assigning
window[namespace] = this
can overwrite an existing
window.mcp
. Add a guard or console warning:- (window as any)[namespace] = this; + if ((window as any)[namespace]) { + console.warn(`window.${namespace} already exists – overwriting.`); + } + (window as any)[namespace] = this;src/winodw.MCP/mcp-window-types.ts (2)
55-60
: Custom error class loses stack trace in some browsersInvoking
super(message)
after assigningdata
prevents the correct
Error.captureStackTrace
behaviour in V8 environments. Swap the order
and setthis.name
explicitly afterwards:- constructor(message: string, public data?: any) { - super(message); - this.name = "McpWindowError"; - } + constructor(message: string, public data?: any) { + super(message); + this.name = 'McpWindowError'; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, McpWindowError); + } + }
321-340
: Empty marker interfaces trigger BiomenoEmptyInterface
warningsInterfaces with no members are equivalent to
{}
; usetype
aliases
to silence linter noise:-export interface ResourceListChangedNotificationPayload {} +export type ResourceListChangedNotificationPayload = {};Repeat for the five other empty interfaces in this section.
🧰 Tools
🪛 Biome (1.9.4)
[error] 321-324: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 331-334: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 336-339: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (5)
app/favicon.ico
is excluded by!**/*.ico
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
public/vite.svg
is excluded by!**/*.svg
src/assets/Cloudflare_Logo.svg
is excluded by!**/*.svg
src/assets/react.svg
is excluded by!**/*.svg
📒 Files selected for processing (35)
.env.example
(0 hunks).gitignore
(1 hunks)README.md
(1 hunks)app/api/chat/route.ts
(0 hunks)app/assistant.tsx
(0 hunks)app/layout.tsx
(0 hunks)app/page.tsx
(0 hunks)eslint.config.js
(1 hunks)eslint.config.mjs
(0 hunks)index.html
(1 hunks)next.config.ts
(0 hunks)package.json
(1 hunks)postcss.config.mjs
(0 hunks)src/App.tsx
(1 hunks)src/Assistant.tsx
(1 hunks)src/components/app-sidebar.tsx
(2 hunks)src/components/assistant-ui/markdown-text.tsx
(1 hunks)src/components/assistant-ui/tool-fallback.tsx
(1 hunks)src/components/ui/sidebar.tsx
(3 hunks)src/index.css
(1 hunks)src/main.tsx
(1 hunks)src/vite-env.d.ts
(1 hunks)src/winodw.MCP/ClientSDK.ts
(1 hunks)src/winodw.MCP/McpContextProviderComponent.tsx
(1 hunks)src/winodw.MCP/mcp-tool-adapter.ts
(1 hunks)src/winodw.MCP/mcp-window-types.ts
(1 hunks)src/winodw.MCP/serverSDK.ts
(1 hunks)src/winodw.MCP/useMcpContextProvider.tsx
(1 hunks)tsconfig.app.json
(1 hunks)tsconfig.json
(1 hunks)tsconfig.node.json
(1 hunks)tsconfig.worker.json
(1 hunks)vite.config.ts
(1 hunks)worker/index.ts
(1 hunks)wrangler.jsonc
(1 hunks)
💤 Files with no reviewable changes (8)
- .env.example
- eslint.config.mjs
- next.config.ts
- app/page.tsx
- app/assistant.tsx
- postcss.config.mjs
- app/api/chat/route.ts
- app/layout.tsx
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/App.tsx (1)
src/Assistant.tsx (1)
Assistant
(11-50)
src/winodw.MCP/McpContextProviderComponent.tsx (1)
src/winodw.MCP/useMcpContextProvider.tsx (1)
useMcpContextProvider
(32-214)
src/winodw.MCP/mcp-tool-adapter.ts (2)
src/winodw.MCP/mcp-window-types.ts (3)
McpInputSchema
(152-158)CallToolParams
(170-174)CallToolResult
(186-191)src/winodw.MCP/ClientSDK.ts (1)
McpWindowClient
(16-104)
src/main.tsx (1)
src/winodw.MCP/serverSDK.ts (1)
McpWindowProvider
(39-216)
src/winodw.MCP/serverSDK.ts (1)
src/winodw.MCP/mcp-window-types.ts (12)
ReadResourceResult
(86-89)CallToolResult
(186-191)GetPromptResult
(243-247)WindowMcpApi
(365-390)ServerInfo
(23-23)ServerCapabilities
(29-38)Resource
(63-71)Tool
(160-168)Prompt
(212-218)ListResourcesResult
(95-99)ListToolsResult
(197-201)ListPromptsResult
(253-257)
src/winodw.MCP/ClientSDK.ts (1)
src/winodw.MCP/mcp-window-types.ts (9)
WindowMcpApi
(365-390)ServerInfo
(23-23)ServerCapabilities
(29-38)ListResourcesResult
(95-99)ReadResourceResult
(86-89)ListToolsResult
(197-201)CallToolResult
(186-191)ListPromptsResult
(253-257)GetPromptResult
(243-247)
🪛 Biome (1.9.4)
tsconfig.worker.json
[error] 6-6: Expected a property but instead found '}'.
Expected a property here.
(parse)
tsconfig.node.json
[error] 9-9: JSON standard does not allow comments.
(parse)
[error] 10-10: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 10-10: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 10-10: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 10-10: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 11-11: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 11-11: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 11-11: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 11-11: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 12-12: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 12-12: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 12-12: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 12-12: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 13-13: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 13-13: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 13-13: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 13-13: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 14-16: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 16-16: JSON standard does not allow comments.
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 24-28: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 29-29: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 30-30: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 30-30: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 30-30: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 30-31: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
src/winodw.MCP/serverSDK.ts
[error] 25-27: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
src/winodw.MCP/mcp-window-types.ts
[error] 124-126: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 133-135: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 276-278: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 321-324: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 331-334: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 336-339: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
tsconfig.app.json
[error] 13-13: JSON standard does not allow comments.
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 19-20: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 20-20: JSON standard does not allow comments.
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 28-28: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 28-28: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 28-32: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 33-33: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 34-34: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 34-34: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 34-36: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 36-37: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
🪛 LanguageTool
README.md
[uncategorized] ~37-~37: Loose punctuation mark.
Context: ...elements). * listResources()
: Discover available resources. *...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~38-~38: Loose punctuation mark.
Context: ...ces. * readResource({ uri })
: Get the content of a specific resource....
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~40-~40: Loose punctuation mark.
Context: ...item to cart). * listTools()
: Discover available tools. * `...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~41-~41: Loose punctuation mark.
Context: ... * callTool({ name, arguments })
: Execute a tool with given arguments. ...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~43-~43: Loose punctuation mark.
Context: ...e's context. * listPrompts()
: Discover available prompt templates. ...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~44-~44: Loose punctuation mark.
Context: ... * getPrompt({ name, arguments })
: Get the messages for a specific prompt,...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~48-~48: Loose punctuation mark.
Context: ...e, version). * getCapabilities()
: Get the capabilities supported by the p...
(UNLIKELY_OPENING_PUNCTUATION)
[style] ~79-~79: This phrase is redundant (‘I’ stands for ‘Interface’). Use simply “APIInterface”.
Context: ...re-list tools, re-read a resource). ## API Interface (WindowMcpApi
) The window.mcp
obje...
(ACRONYM_TAUTOLOGY)
[uncategorized] ~109-~109: Loose punctuation mark.
Context: ...and clients: * McpWindowProviderSDK
: A helper library for web pages to easil...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~114-~114: Loose punctuation mark.
Context: ... notifications. * McpWindowClientSDK
: A helper library for LLM UIs to: * ...
(UNLIKELY_OPENING_PUNCTUATION)
[grammar] ~161-~161: The expression “vice versa” is spelled without hyphens.
Context: ...mplicitly trusted by the LLM client (or vice-versa, depending on how the components are lo...
(VICE_VERSA)
[style] ~178-~178: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...: For list* methods if lists can become very large. Resource Subscriptions: More granular...
(EN_WEAK_ADJECTIVE)
🪛 markdownlint-cli2 (0.17.2)
README.md
68-68: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
69-69: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
70-70: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
71-71: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
110-110: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
111-111: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
112-112: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
113-113: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
115-115: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
116-116: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
117-117: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
121-121: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
146-146: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
🔇 Additional comments (23)
.gitignore (1)
1-29
: .gitignore covers expected files and directories
The ignore patterns correctly exclude logs,node_modules
, Vite build outputs, local env files, editor metadata, and Wrangler artifacts.src/vite-env.d.ts (1)
1-1
: Add Vite environment type declarations
The reference tovite/client
is necessary for recognizing Vite-specific globals and looks correct.src/components/assistant-ui/tool-fallback.tsx (1)
1-1
: Useimport type
for pure type imports
Explicitly markingToolCallContentPartComponent
as a type-only import is correct and ensures no runtime bundle overhead.src/App.tsx (1)
1-8
: NewApp
root component is simple and correct
Rendering theAssistant
component directly fits the restructured Vite app; ensureApp
is mounted inmain.tsx
and that React’s automatic JSX runtime is configured.src/components/assistant-ui/markdown-text.tsx (1)
4-11
: Clean import organization.Import reorganization looks good. Properly marking type imports with the
type
keyword and removing the Next.js-specific "use client" directive aligns well with the migration to Vite.src/components/ui/sidebar.tsx (2)
4-26
: Improved import organization.The reorganization of imports improves code readability by explicitly marking type imports and grouping related imports. The changes are purely organizational with no functional impact.
725-727
: Proper code formatting.Good cleanup by removing the trailing comma from the export list and adding a proper trailing newline at the end of the file.
wrangler.jsonc (1)
15-16
:⚠️ Potential issueInvalid JSON trailing comma
There's a trailing comma after
"enabled": true
but no comma should be present since it's the last property in the object."observability": { "enabled": true - } + },Likely an incorrect or invalid review comment.
tsconfig.node.json (2)
1-31
: Well-structured TypeScript configuration for Node.js environmentThis configuration is properly set up for Node.js-specific files, with appropriate ES2022 target and ES2023 library support. The bundler mode settings and strict type checking options will help maintain code quality.
🧰 Tools
🪛 Biome (1.9.4)
[error] 9-9: JSON standard does not allow comments.
(parse)
[error] 10-10: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 10-10: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 10-10: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 10-10: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 11-11: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 11-11: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 11-11: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 11-11: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 12-12: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 12-12: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 12-12: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 12-12: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 13-13: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 13-13: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 13-13: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 13-13: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: JSON standard does not allow comments.
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-28: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 29-29: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 30-30: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 30-30: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 30-30: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 30-31: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
20-20
:✅ Verification successful
Verify the
erasableSyntaxOnly
option compatibilityThe
erasableSyntaxOnly
option is not commonly used and might be specific to newer TypeScript versions. Ensure it's compatible with your TypeScript version.
🌐 Web query:
What is the erasableSyntaxOnly option in TypeScript and which versions support it?
💡 Result:
The
--erasableSyntaxOnly
option in TypeScript, introduced in version 5.8, restricts the use of certain TypeScript features that cannot be easily removed without affecting runtime behavior. When enabled, TypeScript will raise errors for constructs such as:
enum
declarationsnamespace
andmodule
declarations with runtime code- Parameter properties in classes
- Non-ECMAScript
import =
andexport =
assignmentsThis flag is particularly useful when working with environments like Node.js, which support running TypeScript files directly but only with syntax that can be erased to produce valid JavaScript. By enabling
--erasableSyntaxOnly
, developers can ensure their code is compatible with such environments by avoiding features that require transformation during the build process. (typescriptlang.org)To use this option, include it in your
tsconfig.json
file undercompilerOptions
:{ "compilerOptions": { "erasableSyntaxOnly": true } }This setting will cause TypeScript to emit errors when encountering the restricted constructs mentioned above. (typescriptlang.org)
For more detailed information, refer to the official TypeScript documentation on the
--erasableSyntaxOnly
option. (typescriptlang.org)Citations:
- 1: https://www.typescriptlang.org/tsconfig/erasableSyntaxOnly.html?utm_source=openai
- 2: https://www.typescriptlang.org/tsconfig/erasableSyntaxOnly.html?utm_source=openai
- 3: https://www.typescriptlang.org/tsconfig/erasableSyntaxOnly.html?utm_source=openai
🏁 Script executed:
#!/bin/bash set -e # Extract the TypeScript version declared in package.json (dependencies or devDependencies) if [ -f package.json ]; then jq -r '[.dependencies.typescript, .devDependencies.typescript] | map(select(.!=null)) | .[0] // "Not found"' package.json else echo "package.json not found" fiLength of output: 185
erasableSyntaxOnly
is supported in TS ≥ 5.8
Your project’s TypeScript version is ~5.8.3, so the"erasableSyntaxOnly": true
setting in tsconfig.node.json is valid and requires no changes.🧰 Tools
🪛 Biome (1.9.4)
[error] 20-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
tsconfig.json (1)
1-20
: Well-structured project references for TypeScript compilationThe modular approach with separate configs for app, node, and worker environments is a good practice for a mixed-environment project.
tsconfig.app.json (2)
1-37
: Well-configured TypeScript settings for React applicationThe configuration is properly set up for a React application with appropriate target, module resolution, and JSX settings.
🧰 Tools
🪛 Biome (1.9.4)
[error] 13-13: JSON standard does not allow comments.
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 14-14: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 15-15: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 16-16: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 17-17: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 18-18: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-19: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 19-20: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 20-20: JSON standard does not allow comments.
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 21-21: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 22-22: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 23-23: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 25-25: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 26-26: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 27-27: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 28-28: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 28-28: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 28-32: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 33-33: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 34-34: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 34-34: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 34-36: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 36-37: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
24-24
: Verify theerasableSyntaxOnly
option compatibilitySame as in tsconfig.node.json, this option is not commonly used. Ensure it's compatible with your TypeScript version and has the intended effect.
🧰 Tools
🪛 Biome (1.9.4)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
[error] 24-24: End of file expected
Use an array for a sequence of values:
[1, 2]
(parse)
src/Assistant.tsx (2)
11-15
: LGTM: Runtime initialization looks good.The chat runtime is properly initialized with the correct API endpoint that will connect to the Cloudflare Worker.
17-18
: Good implementation of the MCP context provider.The
McpContextProviderComponent
is correctly positioned to provide MCP functionality to the entire assistant UI.package.json (3)
7-12
: LGTM: Build scripts are properly configured for Vite and Cloudflare.The scripts for development, building, and deployment are well set up for the new architecture.
33-34
:✅ Verification successful
Verify React 19 compatibility with other dependencies.
You're using React 19, which is very recent. Ensure all dependencies are compatible with this version.
🌐 Web query:
Is React 19 compatible with @assistant-ui/react and @assistant-ui/react-ai-sdk?
💡 Result:
As of May 2025, React 19 is the latest stable release of React. The
@assistant-ui/react
library, which provides a customizable user interface for AI chat applications, has been updated to support React 19. The library's roadmap indicates that support for React 19 is included in the 2025 Q1 roadmap, along with support for Tailwind v4 and Next.js 19. (npmjs.com)Similarly, the
@assistant-ui/react-ai-sdk
package, which integrates the Vercel AI SDK with@assistant-ui/react
, has also been updated to support React 19. The latest version of this package was published on May 14, 2025, indicating ongoing maintenance and compatibility with recent React versions. (npmjs.com)Therefore, both
@assistant-ui/react
and@assistant-ui/react-ai-sdk
are compatible with React 19.Citations:
- 1: https://www.npmjs.com/package/%40assistant-ui/react?utm_source=openai
- 2: https://www.npmjs.com/package/%40assistant-ui/react-ai-sdk?utm_source=openai
React 19 Compatibility Confirmed
Both
@assistant-ui/react
and@assistant-ui/react-ai-sdk
have official support for React 19 (per their May 2025 releases), so no additional changes are required.
15-39
:❓ Verification inconclusive
Review the dependency versions for potential vulnerabilities.
With the migration to Vite and new dependencies, it's important to check for any security vulnerabilities.
🏁 Script executed:
#!/bin/bash # Check for vulnerable dependencies npm audit --json | jq '.vulnerabilities'Length of output: 394
Lockfile required before auditing dependencies
The audit failed because there’s no lockfile in the repo. To enable vulnerability checks:
- Generate a lockfile in the project root:
• For npm:npm install --package-lock-only
• For Yarn:yarn install --frozen-lockfile
• For pnpm:pnpm install --lockfile-only
- Commit the new lockfile (
package-lock.json
,yarn.lock
, orpnpm-lock.yaml
)- Rerun the audit:
• npm:npm audit --json | jq '.vulnerabilities'
• Yarn:yarn audit
• pnpm:pnpm audit
Once the lockfile is in place, verify there are no vulnerabilities introduced by the Vite migration or new dependencies.
README.md (2)
1-10
: Excellent introduction to the MCP-Window protocol.The overview provides a clear and concise explanation of what MCP-Window is, its purpose, and how it differs from standard MCP implementations. This helps readers quickly understand the key concept.
21-56
: Well-structured explanation of key concepts.The key concepts section does an excellent job of breaking down the MCP-Window components and their interactions. The categorization of features into resources, tools, and prompts makes the functionality clear.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~37-~37: Loose punctuation mark.
Context: ...elements). *listResources()
: Discover available resources. *...(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~38-~38: Loose punctuation mark.
Context: ...ces. *readResource({ uri })
: Get the content of a specific resource....(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~40-~40: Loose punctuation mark.
Context: ...item to cart). *listTools()
: Discover available tools. * `...(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~41-~41: Loose punctuation mark.
Context: ... *callTool({ name, arguments })
: Execute a tool with given arguments. ...(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~43-~43: Loose punctuation mark.
Context: ...e's context. *listPrompts()
: Discover available prompt templates. ...(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~44-~44: Loose punctuation mark.
Context: ... *getPrompt({ name, arguments })
: Get the messages for a specific prompt,...(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~48-~48: Loose punctuation mark.
Context: ...e, version). *getCapabilities()
: Get the capabilities supported by the p...(UNLIKELY_OPENING_PUNCTUATION)
src/winodw.MCP/mcp-tool-adapter.ts (1)
74-87
: LGTM: The result processing logic is well-structured.The code correctly prioritizes structured content first, then text content, and finally falls back to the raw content. This provides a flexible way to handle various tool response formats.
src/main.tsx (1)
42-46
: Unchecked root element may crash in SSR / tests
document.getElementById('root')!
asserts presence. In SSR or unit tests the element might be missing, throwing immediately. Fail gracefully:-const container = document.getElementById('root')!; -createRoot(container).render( +const container = document.getElementById('root'); +if (container) { + createRoot(container).render( /* … */ -) + ); +} else { + console.error("Root element #root not found – React app not mounted."); +}src/winodw.MCP/serverSDK.ts (1)
1-1
: Directory namewinodw.MCP
looks like a typo
winodw
→window
. Renaming avoids future import confusions.
tsconfig.worker.json
Outdated
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo", | ||
"types": ["./worker-configuration.d.ts", "vite/client"], | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix JSON syntax error: remove trailing comma.
There's a syntax error in your JSON configuration. JSON doesn't allow trailing commas before closing brackets, which will cause parsing errors.
Apply this diff to fix the issue:
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo",
- "types": ["./worker-configuration.d.ts", "vite/client"],
+ "types": ["./worker-configuration.d.ts", "vite/client"]
},
🧰 Tools
🪛 Biome (1.9.4)
[error] 6-6: Expected a property but instead found '}'.
Expected a property here.
(parse)
🤖 Prompt for AI Agents
In tsconfig.worker.json around lines 4 to 6, there is a trailing comma after the
last item in the "types" array, which is invalid JSON syntax. Remove the
trailing comma after "vite/client" to fix the JSON parsing error.
@@ -0,0 +1,6 @@ | |||
import useMcpContextProvider from "./useMcpContextProvider"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directory name contains typo
There's a typo in the directory name: "winodw.MCP" should be "window.MCP"
This typo appears to be in the directory structure itself, not just the import path. Ensure all references to this directory are updated if you rename it.
🤖 Prompt for AI Agents
In src/winodw.MCP/McpContextProviderComponent.tsx at line 1, the directory name
"winodw.MCP" contains a typo and should be corrected to "window.MCP". Rename the
directory from "winodw.MCP" to "window.MCP" in the file system and update all
import paths and references accordingly to reflect this corrected directory
name.
import useMcpContextProvider from "./useMcpContextProvider"; | ||
|
||
export default function McpContextProviderComponent({ children, mcpClientNamespace }: { children: React.ReactNode, mcpClientNamespace?: string}) { | ||
useMcpContextProvider(mcpClientNamespace); | ||
return <>{children}</>; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Component needs to handle hook return values
The component calls useMcpContextProvider
but doesn't use any of the return values like isLoading
, error
, or other MCP context data. This means errors or loading states aren't handled at this level.
Consider exposing the MCP context to consumers by either:
- Creating a React Context and providing the values to children:
- import useMcpContextProvider from "./useMcpContextProvider";
+ import React, { createContext, useContext } from "react";
+ import useMcpContextProvider, { McpContext } from "./useMcpContextProvider";
+ export const McpContext = createContext<McpContext | null>(null);
+ export const useMcp = () => useContext(McpContext);
export default function McpContextProviderComponent({ children, mcpClientNamespace }: { children: React.ReactNode, mcpClientNamespace?: string}) {
- useMcpContextProvider(mcpClientNamespace);
- return <>{children}</>;
+ const mcpContext = useMcpContextProvider(mcpClientNamespace);
+ return (
+ <McpContext.Provider value={mcpContext}>
+ {mcpContext.error ? (
+ <div>Error connecting to MCP: {mcpContext.error.message}</div>
+ ) : mcpContext.isLoading ? (
+ <div>Loading MCP resources...</div>
+ ) : (
+ <>{children}</>
+ )}
+ </McpContext.Provider>
+ );
}
- Or at minimum, handle loading and error states:
export default function McpContextProviderComponent({ children, mcpClientNamespace }: { children: React.ReactNode, mcpClientNamespace?: string}) {
- useMcpContextProvider(mcpClientNamespace);
+ const { isLoading, error } = useMcpContextProvider(mcpClientNamespace);
+
+ if (error) {
+ return <div>Error connecting to MCP: {error.message}</div>;
+ }
+
+ if (isLoading) {
+ return <div>Loading MCP resources...</div>;
+ }
return <>{children}</>;
}
🤖 Prompt for AI Agents
In src/winodw.MCP/McpContextProviderComponent.tsx lines 1 to 6, the component
calls the useMcpContextProvider hook but does not handle or expose its return
values such as isLoading or error. To fix this, modify the component to either
create a React Context that provides these values to its children or at minimum,
add conditional rendering to handle loading and error states before rendering
children. This ensures that consumers of the component can access MCP context
data and that loading or error states are properly managed.
src/components/app-sidebar.tsx
Outdated
<SidebarMenuButton size="lg"> | ||
<a href="https://github.com/assistant-ui/assistant-ui" target="_blank" className="flex items-center gap-2"> | ||
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"> | ||
<Github className="size-4" /> | ||
</div> | ||
<div className="flex flex-col gap-0.5 leading-none"> | ||
<span className="font-semibold">GitHub</span> | ||
<span className="">View Source</span> | ||
</div> | ||
</Link> | ||
</a> | ||
</SidebarMenuButton> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add security attributes to GitHub link
Same issue as with the other external link. The GitHub link should include rel="noopener noreferrer"
for security.
<SidebarMenuButton size="lg">
- <a href="/assistant-ui/assistant-ui" target="_blank" className="flex items-center gap-2">
+ <a href="/assistant-ui/assistant-ui" target="_blank" rel="noopener noreferrer" className="flex items-center gap-2">
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
<Github className="size-4" />
</div>
<div className="flex flex-col gap-0.5 leading-none">
<span className="font-semibold">GitHub</span>
<span className="">View Source</span>
</div>
</a>
</SidebarMenuButton>
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
<SidebarMenuButton size="lg"> | |
<a href="https://github.com/assistant-ui/assistant-ui" target="_blank" className="flex items-center gap-2"> | |
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"> | |
<Github className="size-4" /> | |
</div> | |
<div className="flex flex-col gap-0.5 leading-none"> | |
<span className="font-semibold">GitHub</span> | |
<span className="">View Source</span> | |
</div> | |
</Link> | |
</a> | |
</SidebarMenuButton> | |
<SidebarMenuButton size="lg"> | |
<a | |
href="https://github.com/assistant-ui/assistant-ui" | |
target="_blank" | |
rel="noopener noreferrer" | |
className="flex items-center gap-2" | |
> | |
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"> | |
<Github className="size-4" /> | |
</div> | |
<div className="flex flex-col gap-0.5 leading-none"> | |
<span className="font-semibold">GitHub</span> | |
<span className="">View Source</span> | |
</div> | |
</a> | |
</SidebarMenuButton> |
🤖 Prompt for AI Agents
In src/components/app-sidebar.tsx between lines 43 and 53, the GitHub external
link is missing the security attributes rel="noopener noreferrer". Add these
attributes to the <a> tag to prevent security vulnerabilities related to opening
links in a new tab.
src/components/app-sidebar.tsx
Outdated
<SidebarMenuButton size="lg"> | ||
<a href="https://assistant-ui.com" target="_blank" className="flex items-center gap-2"> | ||
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"> | ||
<MessagesSquare className="size-4" /> | ||
</div> | ||
<div className="flex flex-col gap-0.5 leading-none"> | ||
<span className="font-semibold">assistant-ui</span> | ||
</div> | ||
</Link> | ||
</a> | ||
</SidebarMenuButton> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add security attributes to external links
External links using target="_blank"
should include rel="noopener noreferrer"
to prevent potential security vulnerabilities.
<SidebarMenuButton size="lg">
- <a href="https://assistant-ui.com" target="_blank" className="flex items-center gap-2">
+ <a href="https://assistant-ui.com" target="_blank" rel="noopener noreferrer" className="flex items-center gap-2">
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
<MessagesSquare className="size-4" />
</div>
<div className="flex flex-col gap-0.5 leading-none">
<span className="font-semibold">assistant-ui</span>
</div>
</a>
</SidebarMenuButton>
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
<SidebarMenuButton size="lg"> | |
<a href="https://assistant-ui.com" target="_blank" className="flex items-center gap-2"> | |
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"> | |
<MessagesSquare className="size-4" /> | |
</div> | |
<div className="flex flex-col gap-0.5 leading-none"> | |
<span className="font-semibold">assistant-ui</span> | |
</div> | |
</Link> | |
</a> | |
</SidebarMenuButton> | |
<SidebarMenuButton size="lg"> | |
<a | |
href="https://assistant-ui.com" | |
target="_blank" | |
rel="noopener noreferrer" | |
className="flex items-center gap-2" | |
> | |
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"> | |
<MessagesSquare className="size-4" /> | |
</div> | |
<div className="flex flex-col gap-0.5 leading-none"> | |
<span className="font-semibold">assistant-ui</span> | |
</div> | |
</a> | |
</SidebarMenuButton> |
🤖 Prompt for AI Agents
In src/components/app-sidebar.tsx around lines 21 to 30, the external link with
target="_blank" is missing the security attributes rel="noopener noreferrer".
Add rel="noopener noreferrer" to the <a> tag to prevent potential security
vulnerabilities related to opening links in a new tab.
src/winodw.MCP/serverSDK.ts
Outdated
dispatchMcpEvent(type: McpEvent, payload?: any) { | ||
const event = new CustomEvent<McpNotification>("mcpNotification", { | ||
detail: { type, payload }, | ||
}); | ||
this.dispatchEvent(event); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
McpEvent
/ McpNotification
types are undefined
dispatchMcpEvent
generically parameterises CustomEvent
with McpNotification
, and the
first argument is typed as McpEvent
, yet neither is exported from
mcp-window-types.ts
. This causes unresolved-identifier errors.
Fix options:
-import type { …, McpEvent, McpNotification, … } from './mcp-window-types.ts';
+import type { McpNotificationDetail as McpNotification, /* alias */ }
+ from './mcp-window-types.ts';
+type McpEvent = McpNotification['type'];
or formally export those aliases from the types file.
Without this, the provider cannot compile.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/winodw.MCP/serverSDK.ts around lines 30 to 35, the types McpEvent and
McpNotification used in dispatchMcpEvent are not defined or imported, causing
unresolved identifier errors. To fix this, locate the mcp-window-types.ts file
and ensure that McpEvent and McpNotification types are properly exported from
there. Then, import these types into serverSDK.ts so they can be referenced
without errors.
src/winodw.MCP/serverSDK.ts
Outdated
private zodToMcpSchema(schema: ZodSchema<any, ZodTypeDef, any>): ToolInputSchema { | ||
// Basic Zod to JSON Schema-like conversion (can be made more robust) | ||
if (schema instanceof z.ZodObject) { | ||
const properties: ToolInputSchema['properties'] = {}; | ||
const shape = schema.shape as Record<string, ZodSchema<any, ZodTypeDef, any>>; | ||
for (const key in shape) { | ||
const fieldSchema = shape[key]; | ||
let type = 'any'; | ||
if (fieldSchema instanceof z.ZodString) type = 'string'; | ||
else if (fieldSchema instanceof z.ZodNumber) type = 'number'; | ||
else if (fieldSchema instanceof z.ZodBoolean) type = 'boolean'; | ||
else if (fieldSchema instanceof z.ZodArray) type = 'array'; | ||
else if (fieldSchema instanceof z.ZodObject) type = 'object'; | ||
properties[key] = { type, description: fieldSchema.description }; | ||
} | ||
return { type: 'object', properties, required: Object.keys(shape) /* simplistic */ }; | ||
} | ||
return { type: 'object', properties: {} }; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
zodToMcpSchema
treats every property as required
required: Object.keys(shape)
marks all keys mandatory, ignoring Zod’s
.optional()
. Tools that rely on optional arguments will mis-validate.
Either:
- Inspect
fieldSchema.isOptional()
(available in Zod ≥3.22) or - Use
schema.safeParse({})
heuristics to collect required keys.
Example patch:
const required: string[] = [];
for (const key in shape) {
const fieldSchema = shape[key];
+ if (!(fieldSchema.isOptional?.() ?? false)) {
+ required.push(key);
+ }
…
}
-return { type: 'object', properties, required: Object.keys(shape) };
+return { type: 'object', properties, required };
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/winodw.MCP/serverSDK.ts lines 104 to 122, the zodToMcpSchema method
incorrectly marks all properties as required by setting required to all keys in
the schema shape, ignoring optional fields. To fix this, update the code to
check each fieldSchema for optionality using fieldSchema.isOptional() and only
include keys that are not optional in the required array. This ensures the
generated schema correctly reflects which properties are mandatory and which are
optional.
src/winodw.MCP/serverSDK.ts
Outdated
addTool<T extends z.ZodRawShape>( | ||
tool: Omit<Tool, 'inputSchema'> & { inputSchemaDef?: T, inputSchema?: ToolInputSchema }, | ||
handler: (args: z.infer<z.ZodObject<T>>) => Promise<CallToolResult> | ||
): void { | ||
if (!this.capabilities.tools) throw new Error("Tool capability not enabled."); | ||
let validator; | ||
if (tool.inputSchemaDef) { | ||
validator = z.object(tool.inputSchemaDef); | ||
} | ||
this.tools.set(tool.name, { | ||
...tool, | ||
inputSchema: tool.inputSchema || (tool.inputSchemaDef ? this.zodToMcpSchema(validator!) : { type: 'object', properties: {} }), | ||
handler: async (params) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ToolInputSchema
is not declared anywhere
The generic overload refers to ToolInputSchema
, but only McpInputSchema
exists in the shared types module. Rename to the exported type or add an alias:
- tool: Omit<Tool, 'inputSchema'> & { inputSchemaDef?: T, inputSchema?: ToolInputSchema },
+ tool: Omit<Tool, 'inputSchema'> & { inputSchemaDef?: T, inputSchema?: McpInputSchema },
This is a hard compile failure.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
addTool<T extends z.ZodRawShape>( | |
tool: Omit<Tool, 'inputSchema'> & { inputSchemaDef?: T, inputSchema?: ToolInputSchema }, | |
handler: (args: z.infer<z.ZodObject<T>>) => Promise<CallToolResult> | |
): void { | |
if (!this.capabilities.tools) throw new Error("Tool capability not enabled."); | |
let validator; | |
if (tool.inputSchemaDef) { | |
validator = z.object(tool.inputSchemaDef); | |
} | |
this.tools.set(tool.name, { | |
...tool, | |
inputSchema: tool.inputSchema || (tool.inputSchemaDef ? this.zodToMcpSchema(validator!) : { type: 'object', properties: {} }), | |
handler: async (params) => { | |
addTool<T extends z.ZodRawShape>( | |
tool: Omit<Tool, 'inputSchema'> & { inputSchemaDef?: T, inputSchema?: McpInputSchema }, | |
handler: (args: z.infer<z.ZodObject<T>>) => Promise<CallToolResult> | |
): void { | |
if (!this.capabilities.tools) throw new Error("Tool capability not enabled."); | |
let validator; | |
if (tool.inputSchemaDef) { | |
validator = z.object(tool.inputSchemaDef); | |
} | |
this.tools.set(tool.name, { | |
...tool, | |
inputSchema: tool.inputSchema || (tool.inputSchemaDef ? this.zodToMcpSchema(validator!) : { type: 'object', properties: {} }), | |
handler: async (params) => { |
🤖 Prompt for AI Agents
In src/winodw.MCP/serverSDK.ts between lines 73 and 85, the type ToolInputSchema
used in the addTool method is not declared anywhere, causing a compile error.
Replace ToolInputSchema with the correct exported type McpInputSchema from the
shared types module or create an alias for ToolInputSchema that points to
McpInputSchema. This will resolve the type reference and fix the compilation
failure.
src/winodw.MCP/mcp-window-types.ts
Outdated
export interface McpInputSchema { | ||
type: "object"; | ||
properties?: { [key: string]: { type: string; description?: string; [key: string]: any } }; | ||
required?: string[]; | ||
// passthrough | ||
[key: string]: any; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Export ToolInputSchema
alias for SDK compatibility
serverSDK.ts
expects ToolInputSchema
, but only McpInputSchema
is
defined. Provide a simple alias to keep both names working:
export interface McpInputSchema {
…
}
+
+// Back-compat alias – remove once all call-sites migrate.
+export type ToolInputSchema = McpInputSchema;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export interface McpInputSchema { | |
type: "object"; | |
properties?: { [key: string]: { type: string; description?: string; [key: string]: any } }; | |
required?: string[]; | |
// passthrough | |
[key: string]: any; | |
} | |
export interface McpInputSchema { | |
type: "object"; | |
properties?: { [key: string]: { type: string; description?: string; [key: string]: any } }; | |
required?: string[]; | |
// passthrough | |
[key: string]: any; | |
} | |
// Back-compat alias – remove once all call-sites migrate. | |
export type ToolInputSchema = McpInputSchema; |
🤖 Prompt for AI Agents
In src/winodw.MCP/mcp-window-types.ts around lines 152 to 158, the interface
McpInputSchema is defined but the SDK expects an alias named ToolInputSchema.
Add an export statement that creates a type alias ToolInputSchema for
McpInputSchema to maintain compatibility with serverSDK.ts without changing the
existing interface.
src/winodw.MCP/mcp-window-types.ts
Outdated
export type McpNotificationDetail = | ||
| ({ type: "resourcesListChanged" } & ResourceListChangedNotificationPayload) | ||
| ({ type: "resourceUpdated" } & ResourceUpdatedNotificationPayload) | ||
| ({ type: "toolsListChanged" } & ToolListChangedNotificationPayload) | ||
| ({ type: "promptsListChanged" } & PromptListChangedNotificationPayload) | ||
| ({ type: "loggingMessage" } & LoggingMessageNotificationPayload); // Renamed from "notifications/message" | ||
|
||
// The CustomEvent detail type | ||
export interface McpNotificationEventDetail { | ||
type: McpNotificationDetail['type']; // The specific notification type | ||
payload?: Omit<McpNotificationDetail, 'type'>; // The payload for that type | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add canonical McpEvent
/ McpNotification
type exports
The provider dispatches events with type
plus payload. Supplying
formal aliases eases consumption and fixes missing-type errors noted
in serverSDK.ts
.
export type McpNotificationDetail =
…
| ({ type: "loggingMessage" } & LoggingMessageNotificationPayload); // Renamed from "notifications/message"
+// Convenience aliases -------------------------------------------------
+export type McpEvent = McpNotificationDetail['type'];
+export type McpNotification = McpNotificationDetail;
🤖 Prompt for AI Agents
In src/winodw.MCP/mcp-window-types.ts around lines 349 to 360, add explicit type
aliases named McpEvent and McpNotification that represent the union of event
types with their payloads, matching the dispatched event structure. This will
provide canonical exports for these types, making it easier to consume them
elsewhere and resolving missing-type errors in serverSDK.ts. Define McpEvent and
McpNotification as unions of objects containing the type and corresponding
payload, aligning with the existing McpNotificationDetail and
McpNotificationEventDetail structures.
@Yonom
I've been really interested in the work you are doing with allowing the model to call tools on the page. It got me thinking if the model context protocol could be implemented in browser where the website maintainer can define an "MCP server" which automatically gets picked up by the the model in the chat UI on load
This PR has a working implementation of this idea. It needs serious cleanup, but I think this idea has alot of potential.
let me walk you through it:
like a regular MCP server, the website owner runs this JS at some point (in this case it's before the react component mounts)
Now that the mcp server has been exposed on the window as
window.mcp
the MCP client can pick it up. This is a bit redundant in the browser version but I'm trying my best to match the existing protocol. (you can check it out atCliendSDK.ts
)now we can use the client like this:
I went ahead and created a client integration to Assistant-UI using the
tool
function exported by your lib:basically what we are doing here is reading the tools from the browser mcp server, converting them to the assistant Ui tool format then registering them with the runtime (and some system prompt to tell the model how to use it)
since this all happens in a hook we just create a context for it and wrap the chat ui in that context:
Here is s demo of it working: