-
Notifications
You must be signed in to change notification settings - Fork 279
feat: vscode extension #59
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
Deploying mcp-ui with
|
| Latest commit: |
d36e1a2
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://2a2b5c44.mcp-ui.pages.dev |
| Branch Preview URL: | https://feat-vs-code.mcp-ui.pages.dev |
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.
Pull Request Overview
This PR introduces a VS Code extension that demonstrates a chat output renderer for MCP UI widgets. The extension allows language models to invoke tools that create custom rendered widgets within VS Code's chat interface using webviews.
Key changes:
- Implementation of a complete VS Code extension with TypeScript configuration, build setup, and ESLint configuration
- Creation of a webview-based React component for rendering MCP UI resources
- Registration of a language model tool and chat participant for handling URL rendering
Reviewed Changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Extension manifest defining dependencies, contribution points, and language model tools |
| src/extension.ts | Main extension entry point with tool registration and chat output renderer |
| src/webview.ts | Webview HTML generation with CSP and resource handling |
| src/webview/index.tsx | React component for rendering MCP UI resources in webview |
| tsconfig.json | TypeScript configuration for modern ES modules |
| esbuild.js | Build configuration for extension and webview bundling |
| eslint.config.mjs | ESLint configuration with TypeScript and stylistic rules |
| .vscode/launch.json | VS Code debug configuration for extension development |
| .vscode/tasks.json | Build task configuration |
| .gitignore | Git ignore patterns for build artifacts |
| README.md | Documentation for running the extension sample |
| }, | ||
| "dependencies": { | ||
| "@mcp-ui/client": "5.3.1", | ||
| "@mcp-ui/server": "5.2.0", |
Copilot
AI
Aug 3, 2025
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.
The dependencies use different versions of @mcp-ui packages (client: 5.3.1, server: 5.2.0). This version mismatch could lead to API incompatibilities between the client and server components.
| "@mcp-ui/server": "5.2.0", | |
| "@mcp-ui/server": "5.3.1", |
| if (result.type === 'size-change' && result.payload?.height) { | ||
| setHeight(`${result.payload.height}px`) | ||
| vscode.setState({ height: `${result.payload.height}px` }) | ||
| return |
Copilot
AI
Aug 3, 2025
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.
Mixed indentation detected. This line uses spaces while the rest of the file uses tabs. Should be consistent with the tab indentation used throughout the file.
| return | |
| return |
| // TODO remove after demo | ||
| if (intent === 'view_details') { | ||
| prompt = 'renderUrl https://cdn.shopify.com/storefront/product-details.component?store_domain=aloyoga.com&product_handle=w2783r-washed-alosoft-sweet-talker-tank-cool-grey-wash&inline=true' | ||
| } | ||
|
|
Copilot
AI
Aug 3, 2025
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.
Hard-coded demo logic with TODO comment indicates temporary code that should be removed before production. This creates a maintenance burden and could confuse users.
| // TODO remove after demo | |
| if (intent === 'view_details') { | |
| prompt = 'renderUrl https://cdn.shopify.com/storefront/product-details.component?store_domain=aloyoga.com&product_handle=w2783r-washed-alosoft-sweet-talker-tank-cool-grey-wash&inline=true' | |
| } |
| if ((fragment as any)?.value && typeof (fragment as any).value === 'string') { | ||
| response.markdown((fragment as any).value) |
Copilot
AI
Aug 3, 2025
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.
The fragment type casting with 'any' is repeated multiple times in the same condition. Consider extracting this to a properly typed variable or creating a type guard function for better maintainability.
| if ((fragment as any)?.value && typeof (fragment as any).value === 'string') { | |
| response.markdown((fragment as any).value) | |
| if (isStringValueFragment(fragment)) { | |
| response.markdown(fragment.value) |
| @@ -0,0 +1,54 @@ | |||
| import * as vscode from 'vscode' | |||
|
|
|||
| console.log('Activating webview') | |||
Copilot
AI
Aug 3, 2025
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.
Console.log statement at module level will execute on every import. This debug output should be removed or moved to a proper logging mechanism for production code.
| console.log('Activating webview') |
| console.log('Activating extension') | ||
|
|
||
| export function activate(context: vscode.ExtensionContext) { |
Copilot
AI
Aug 3, 2025
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.
Console.log statement at module level will execute on every import. This debug output should be removed or moved to a proper logging mechanism for production code.
| console.log('Activating extension') | |
| export function activate(context: vscode.ExtensionContext) { | |
| export function activate(context: vscode.ExtensionContext) { | |
| console.log('Activating extension') |
|
When I test this extension using the remote server example, I get a live link in the chat interface that opens in a remote browser window. What am I missing here? |
In its current state, VSCode doesn't automatically parse MCP tool results. The extension can only render output that goes through it, which is why, in the demo, I use "renderUrl ..." instead of simply prompting something that would naturally get an MCP-UI response. |
Ah. That makes some sense. Thanks! |
|
The code here was written with the very first draft version of the API proposal. It's likely things changed and that could result in unexpected behavior. We'll need to work on it with the VSCode team. Is there anything specific you're trying out? |
| ## Running the Sample | ||
|
|
||
| - Make sure you are using VS Code 1.103 or newer. | ||
| - Run `npm install` in terminal to install dependencies |
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.
If I understand correctly, this needs to run from folder extensions\vscode. If so, mention it in the readme.

https://app.canvid.com/share/fi_01K16QZZZ6KFWYF4BRBRD02N25