-
Notifications
You must be signed in to change notification settings - Fork 2.1k
enhance MCP connect dialog #57047
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
Merged
Merged
enhance MCP connect dialog #57047
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
3bf32b1
beautify MCP connect dialog
greedy52 cddb957
refactor(web): add cursor and mcp vscode install buttons
gabrielcorado 1d46cfb
move helpers to shared package in case need to support Connect
greedy52 b4d6bec
rename AppLinks to InstallLinks and
greedy52 8d06985
review comments
greedy52 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions
1
web/packages/design/src/ResourceIcon/assets/mcpcursor-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions
1
web/packages/design/src/ResourceIcon/assets/mcpvscodeinsiders.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| /** | ||
| * Teleport | ||
| * Copyright (C) 2025 Gravitational, Inc. | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU Affero General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU Affero General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Affero General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| import { | ||
| generateClaudeDesktopConfigForApp, | ||
| generateInstallLinksForApp, | ||
| } from 'shared/services/mcp/client'; | ||
|
|
||
| describe('generateClaudeDesktopConfigForApp', () => { | ||
| it('generates the correct config JSON', () => { | ||
| const outputJSON = generateClaudeDesktopConfigForApp('demo-test'); | ||
|
|
||
| expect(outputJSON).toBe(`{ | ||
| "mcpServers": { | ||
| "teleport-mcp-demo-test": { | ||
| "command": "tsh", | ||
| "args": [ | ||
| "mcp", | ||
| "connect", | ||
| "demo-test" | ||
| ] | ||
| } | ||
| } | ||
| }`); | ||
| }); | ||
| }); | ||
|
|
||
| describe('generateInstallLinksForApp', () => { | ||
| it('generates the correct links', () => { | ||
| const links = generateInstallLinksForApp('demo-test'); | ||
| expect(links).toEqual({ | ||
| cursor: | ||
| 'cursor://anysphere.cursor-deeplink/mcp/install?name=teleport-mcp-demo-test&config=eyJjb21tYW5kIjoidHNoIiwiYXJncyI6WyJtY3AiLCJjb25uZWN0IiwiZGVtby10ZXN0Il19', | ||
| vscode: | ||
| 'vscode:mcp/install?%7B%22name%22%3A%22teleport-mcp-demo-test%22%2C%22command%22%3A%22tsh%22%2C%22args%22%3A%5B%22mcp%22%2C%22connect%22%2C%22demo-test%22%5D%7D', | ||
| vscodeInsiders: | ||
| 'vscode-insiders:mcp/install?%7B%22name%22%3A%22teleport-mcp-demo-test%22%2C%22command%22%3A%22tsh%22%2C%22args%22%3A%5B%22mcp%22%2C%22connect%22%2C%22demo-test%22%5D%7D', | ||
| }); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| /** | ||
| * Teleport | ||
| * Copyright (C) 2025 Gravitational, Inc. | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU Affero General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU Affero General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Affero General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| export type MCPServerConfig = { | ||
| command: string; | ||
| args: string[]; | ||
| }; | ||
|
|
||
| function mcpServerNameForApp(appName: string): string { | ||
| return `teleport-mcp-${appName}`; | ||
| } | ||
|
|
||
| function mcpServerConfigForApp(appName: string): MCPServerConfig { | ||
| return { | ||
| // TODO(greedy52) we might need different command path and TELEPORT_HOME | ||
| // env var for Teleport Connect. | ||
| command: 'tsh', | ||
| args: ['mcp', 'connect', appName], | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * generateClaudeDesktopConfigForApp generates a prettified JSON config with | ||
| * details to launch the MCP server app with tsh in Claude Desktop format. | ||
| */ | ||
| export function generateClaudeDesktopConfigForApp(appName: string): string { | ||
| const claudeConfig = { | ||
| mcpServers: { | ||
| [mcpServerNameForApp(appName)]: mcpServerConfigForApp(appName), | ||
| }, | ||
| }; | ||
| return JSON.stringify(claudeConfig, null, 2); | ||
| } | ||
|
|
||
| export type InstallLinks = { | ||
| cursor: string; | ||
| vscode: string; | ||
| vscodeInsiders: string; | ||
| }; | ||
|
|
||
| /** | ||
| * generateInstallLinksForApp generates links that can be used to install the MCP | ||
| * server app (that runs via tsh) for various MCP clients like cursor. | ||
| */ | ||
| export function generateInstallLinksForApp(appName: string): InstallLinks { | ||
| const name = mcpServerNameForApp(appName); | ||
| const config = mcpServerConfigForApp(appName); | ||
|
|
||
| // Cursor Deeplink | ||
| // https://docs.cursor.com/tools/developers | ||
| const cursorLink = new URL('cursor://anysphere.cursor-deeplink/mcp/install'); | ||
| cursorLink.searchParams.set('name', name); | ||
| cursorLink.searchParams.set('config', btoa(JSON.stringify(config))); | ||
|
|
||
| // VSCode | ||
| // https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_url-handler | ||
| const vscodeEncodedConfig = encodeURIComponent( | ||
| JSON.stringify({ | ||
| name, | ||
| ...config, | ||
| }) | ||
| ); | ||
| return { | ||
| cursor: cursorLink.toString(), | ||
| vscode: `vscode:mcp/install?${vscodeEncodedConfig}`, | ||
| vscodeInsiders: `vscode-insiders:mcp/install?${vscodeEncodedConfig}`, | ||
| }; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| /** | ||
| * Teleport | ||
| * Copyright (C) 2025 Gravitational, Inc. | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU Affero General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU Affero General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Affero General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| export * from './client'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Regarding a possible Connect implementation: This will be a bit of a pain to move to Connect. All external links are blocked by default, with a few exceptions, like hosts of currently added clusters, goteleport.com so that we can link to the docs.
The general principle we try to follow is that even if an attacker manages to get XSS in Connect, we want to limit how they might exploit it. In this case it means allowing access only to a trusted set of hosts.
With the deep links to Cursor and VSCode, I suppose we'd need to grant blanket access to
mcp/installwith any config because I don't see how we could restrict it in a more granular fashion.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 install links has special schemas like
cursor://,vscode://and they open those desktop apps, a little different fromhttps://. maybe we need to re-evaluate the security risk for those. well, once the desktop app opens the install link, usually it's a dialog confirm on the MCP server config to be added.so i think for Connect maybe we can whitelist the install links, with the schema, but without the parameters. if we need to do extra validations, we can extract details from the parameters like validating correct command is used.