Skip to content

Commit 2b10e9b

Browse files
authored
fix mcp servers welcome view (microsoft#252355)
* fix mcp servers welcome view * simplify description
1 parent 7e6672b commit 2b10e9b

File tree

2 files changed

+46
-23
lines changed

2 files changed

+46
-23
lines changed

src/vs/workbench/contrib/mcp/browser/mcpServersView.ts

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import './media/mcpServersView.css';
77
import * as dom from '../../../../base/browser/dom.js';
88
import { ActionBar } from '../../../../base/browser/ui/actionbar/actionbar.js';
9-
import { Button } from '../../../../base/browser/ui/button/button.js';
109
import { IListContextMenuEvent, IListRenderer } from '../../../../base/browser/ui/list/list.js';
1110
import { Event } from '../../../../base/common/event.js';
1211
import { combinedDisposable, Disposable, DisposableStore, dispose, IDisposable, isDisposable } from '../../../../base/common/lifecycle.js';
@@ -21,7 +20,6 @@ import { IKeybindingService } from '../../../../platform/keybinding/common/keybi
2120
import { WorkbenchPagedList } from '../../../../platform/list/browser/listService.js';
2221
import { INotificationService } from '../../../../platform/notification/common/notification.js';
2322
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
24-
import { defaultButtonStyles } from '../../../../platform/theme/browser/defaultStyles.js';
2523
import { IThemeService } from '../../../../platform/theme/common/themeService.js';
2624
import { getLocationBasedViewColors, ViewPane } from '../../../browser/parts/views/viewPane.js';
2725
import { IViewletViewOptions } from '../../../browser/parts/views/viewsViewlet.js';
@@ -40,17 +38,25 @@ import { IWorkbenchContribution } from '../../../common/contributions.js';
4038
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
4139
import { DefaultViewsContext, SearchMcpServersContext } from '../../extensions/common/extensions.js';
4240
import { VIEW_CONTAINER } from '../../extensions/browser/extensions.contribution.js';
41+
import { renderMarkdown } from '../../../../base/browser/markdownRenderer.js';
42+
import { MarkdownString } from '../../../../base/common/htmlContent.js';
4343

4444
export interface McpServerListViewOptions {
4545
showWelcomeOnEmpty?: boolean;
4646
}
4747

48+
interface IQueryResult {
49+
showWelcomeContent: boolean;
50+
model: IPagedModel<IWorkbenchMcpServer>;
51+
}
52+
4853
export class McpServersListView extends ViewPane {
4954

5055
private list: WorkbenchPagedList<IWorkbenchMcpServer> | null = null;
5156
private listContainer: HTMLElement | null = null;
5257
private welcomeContainer: HTMLElement | null = null;
5358
private readonly contextMenuActionRunner = this._register(new ActionRunner());
59+
private input: IQueryResult | undefined;
5460

5561
constructor(
5662
private readonly mpcViewOptions: McpServerListViewOptions,
@@ -106,6 +112,10 @@ export class McpServersListView extends ViewPane {
106112
this.mcpWorkbenchService.open(options.element!, options.editorOptions);
107113
}));
108114
this._register(this.list.onContextMenu(e => this.onContextMenu(e), this));
115+
116+
if (this.input) {
117+
this.renderInput();
118+
}
109119
}
110120

111121
private async onContextMenu(e: IListContextMenuEvent<IWorkbenchMcpServer>): Promise<void> {
@@ -145,16 +155,29 @@ export class McpServersListView extends ViewPane {
145155
}
146156

147157
async show(query: string): Promise<IPagedModel<IWorkbenchMcpServer>> {
148-
if (!this.list) {
149-
return new PagedModel([]);
158+
if (this.input) {
159+
this.input = undefined;
150160
}
151161

152162
query = query.trim();
153163
const servers = query ? await this.mcpWorkbenchService.queryGallery({ text: query.replace('@mcp', '') }) : await this.mcpWorkbenchService.queryLocal();
154-
this.list.model = new DelayedPagedModel(new PagedModel(servers));
164+
const showWelcomeContent = !this.mcpGalleryService.isEnabled() && servers.length === 0 && !!this.mpcViewOptions.showWelcomeOnEmpty;
155165

156-
this.showWelcomeContent(!this.mcpGalleryService.isEnabled() && servers.length === 0 && !!this.mpcViewOptions.showWelcomeOnEmpty);
157-
return this.list.model;
166+
const model = new PagedModel(servers);
167+
this.input = { model, showWelcomeContent };
168+
this.renderInput();
169+
170+
return model;
171+
}
172+
173+
private renderInput() {
174+
if (!this.input) {
175+
return;
176+
}
177+
if (this.list) {
178+
this.list.model = new DelayedPagedModel(this.input.model);
179+
}
180+
this.showWelcomeContent(this.input.showWelcomeContent);
158181
}
159182

160183
private showWelcomeContent(show: boolean): void {
@@ -173,17 +196,19 @@ export class McpServersListView extends ViewPane {
173196
title.textContent = localize('mcp.welcome.title', "MCP Servers");
174197

175198
const description = dom.append(welcomeContent, dom.$('.mcp-welcome-description'));
176-
description.textContent = localize('mcp.welcome.description', "Extend agent mode by installing MCP servers to bring extra tools for connecting to databases, invoking APIs, performing specialized tasks, etc.");
177-
178-
// Browse button
179-
const buttonContainer = dom.append(welcomeContent, dom.$('.mcp-welcome-button-container'));
180-
const button = this._register(new Button(buttonContainer, {
181-
title: localize('mcp.welcome.browseButton', "Browse MCP Servers"),
182-
...defaultButtonStyles
199+
const browseUrl = this.productService.quality === 'insider' ? 'https://code.visualstudio.com/insider/mcp' : 'https://code.visualstudio.com/mcp';
200+
const markdownResult = this._register(renderMarkdown(new MarkdownString(
201+
localize('mcp.welcome.descriptionWithLink', "Extend agent mode by installing [MCP servers]({0}) to bring extra tools for connecting to databases, invoking APIs, performing specialized tasks, etc.", browseUrl),
202+
{ isTrusted: true }
203+
), {
204+
actionHandler: {
205+
callback: (content: string) => {
206+
this.openerService.open(URI.parse(content));
207+
},
208+
disposables: this._store
209+
}
183210
}));
184-
button.label = localize('mcp.welcome.browseButton', "Browse MCP Servers");
185-
186-
this._register(button.onDidClick(() => this.openerService.open(URI.parse(this.productService.quality === 'insider' ? 'https://code.visualstudio.com/insider/mcp' : 'https://code.visualstudio.com/mcp'))));
211+
description.appendChild(markdownResult.element);
187212
}
188213

189214
}

src/vs/workbench/contrib/mcp/browser/media/mcpServersView.css

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,11 @@
3737
max-width: 350px;
3838
padding: 0 20px;
3939
margin-top: 26px;
40-
}
4140

42-
.mcp-welcome-button-container {
43-
margin-top: 24px;
44-
margin-bottom: 24px;
45-
max-width: 300px;
46-
width: 100%;
41+
a {
42+
color: var(--vscode-textLink-foreground);
43+
}
4744
}
45+
4846
}
4947
}

0 commit comments

Comments
 (0)