- Access the app at:
+
+ {isMcp
+ ? 'Access the MCP server with a streamable-HTTP-compatible client like "mcp-remote" at:'
+ : 'Access the app at:'}
+
diff --git a/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx b/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx
index 38eb65561cc31..0d1ad3c152fae 100644
--- a/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx
+++ b/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx
@@ -34,7 +34,7 @@ import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspace
import * as types from 'teleterm/ui/services/workspacesService';
type StoryProps = {
- appType: 'web' | 'tcp' | 'tcp-multi-port';
+ appType: 'web' | 'tcp' | 'tcp-multi-port' | 'mcp';
online: boolean;
changeLocalPort: 'succeed' | 'throw-error';
changeTargetPort: 'succeed' | 'throw-error';
@@ -48,7 +48,7 @@ const meta: Meta = {
argTypes: {
appType: {
control: { type: 'radio' },
- options: ['web', 'tcp', 'tcp-multi-port'],
+ options: ['web', 'tcp', 'tcp-multi-port', 'mcp'],
},
changeLocalPort: {
if: { arg: 'online' },
@@ -93,6 +93,9 @@ export function Story(props: StoryProps) {
gateway.protocol = 'TCP';
gateway.targetSubresourceName = '4242';
}
+ if (props.appType === 'mcp') {
+ gateway.protocol = 'MCP';
+ }
const documentGateway: types.DocumentGateway = {
kind: 'doc.gateway',
targetUri: '/clusters/bar/apps/quux',
diff --git a/web/packages/teleterm/src/ui/TopBar/Connections/Connections.story.tsx b/web/packages/teleterm/src/ui/TopBar/Connections/Connections.story.tsx
index 8dfc3d6c3975b..8a34aec7bca6e 100644
--- a/web/packages/teleterm/src/ui/TopBar/Connections/Connections.story.tsx
+++ b/web/packages/teleterm/src/ui/TopBar/Connections/Connections.story.tsx
@@ -281,6 +281,30 @@ const makeConnections = (index = 0) => {
login: 'casey',
clusterName: 'teleport.example.sh',
},
+ {
+ connected: true,
+ kind: 'connection.gateway' as const,
+ title: 'some-web-app' + suffix,
+ targetName: 'some-web-app',
+ id: '11111' + suffix,
+ targetUri: '/clusters/foo/apps/some-web-app' + suffix,
+ port: '11111',
+ gatewayUri: '/gateways/some-web-app',
+ clusterName: 'teleport.example.sh',
+ targetProtocol: 'HTTP',
+ },
+ {
+ connected: true,
+ kind: 'connection.gateway' as const,
+ title: 'some-mcp-server' + suffix,
+ targetName: 'some-mcp-server',
+ id: '22222' + suffix,
+ targetUri: '/clusters/foo/apps/some-mcp-server' + suffix,
+ port: '22222',
+ gatewayUri: '/gateways/some-mcp-server',
+ clusterName: 'teleport.example.sh',
+ targetProtocol: 'MCP',
+ },
];
};
diff --git a/web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionItem.tsx b/web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionItem.tsx
index d5c1953afdad2..1183a4faec518 100644
--- a/web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionItem.tsx
+++ b/web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionItem.tsx
@@ -158,6 +158,9 @@ function getKindName(connection: ExtendedTrackedConnection): string {
switch (connection.kind) {
case 'connection.gateway':
if (isAppUri(connection.targetUri)) {
+ if (connection.targetProtocol === 'MCP') {
+ return 'MCP';
+ }
return 'APP';
}
if (isDatabaseUri(connection.targetUri)) {
diff --git a/web/packages/teleterm/src/ui/services/connectionTracker/trackedConnectionUtils.ts b/web/packages/teleterm/src/ui/services/connectionTracker/trackedConnectionUtils.ts
index 10aecd311154d..86cd3161cecc7 100644
--- a/web/packages/teleterm/src/ui/services/connectionTracker/trackedConnectionUtils.ts
+++ b/web/packages/teleterm/src/ui/services/connectionTracker/trackedConnectionUtils.ts
@@ -183,6 +183,7 @@ export function createGatewayConnection(
targetUser: document.targetUser,
targetName: document.targetName,
targetSubresourceName: document.targetSubresourceName,
+ targetProtocol: document.targetProtocol,
};
}
diff --git a/web/packages/teleterm/src/ui/services/connectionTracker/types.ts b/web/packages/teleterm/src/ui/services/connectionTracker/types.ts
index 013781d42ffb1..c9f5ddfcb2c48 100644
--- a/web/packages/teleterm/src/ui/services/connectionTracker/types.ts
+++ b/web/packages/teleterm/src/ui/services/connectionTracker/types.ts
@@ -44,6 +44,7 @@ export interface TrackedGatewayConnection extends TrackedConnectionBase {
targetUser?: string;
port?: string;
targetSubresourceName?: string;
+ targetProtocol?: string;
}
export interface TrackedKubeConnection extends TrackedConnectionBase {
diff --git a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/connectToApp.test.ts b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/connectToApp.test.ts
index 95e843367609e..b0c4569ff67c3 100644
--- a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/connectToApp.test.ts
+++ b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/connectToApp.test.ts
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+import { getAppProtocol } from 'shared/services/apps';
+
import { makeApp, makeRootCluster } from 'teleterm/services/tshd/testHelpers';
import { MockAppContext } from 'teleterm/ui/fixtures/mocks';
import {
@@ -113,6 +115,7 @@ describe('connectToApp', () => {
targetUser: '',
title: 'foo',
uri: expect.any(String),
+ targetProtocol: 'TCP',
});
});
});
@@ -147,6 +150,7 @@ describe('setUpAppGateway', () => {
await setUpAppGateway(appContext, app.uri, {
telemetry: { origin: 'resource_table' },
targetPort,
+ targetProtocol: getAppProtocol(app.endpointUri),
});
const documents = appContext.workspacesService
.getActiveWorkspaceDocumentService()
@@ -164,6 +168,7 @@ describe('setUpAppGateway', () => {
targetUser: '',
title: expectedTitle || 'foo',
uri: expect.any(String),
+ targetProtocol: getAppProtocol(app.endpointUri),
});
});
});
diff --git a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/connectToApp.ts b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/connectToApp.ts
index 8343dca0cc6fe..3102f5ca77f07 100644
--- a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/connectToApp.ts
+++ b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/connectToApp.ts
@@ -17,6 +17,7 @@
*/
import { App } from 'gen-proto-ts/teleport/lib/teleterm/v1/app_pb';
+import { getAppProtocol } from 'shared/services/apps';
import {
getAwsAppLaunchUrl,
@@ -121,7 +122,12 @@ export async function connectToApp(
targetPort = target.tcpPorts[0].port;
}
- await setUpAppGateway(ctx, target.uri, { telemetry, targetPort });
+ const targetProtocol = getAppProtocol(target.endpointUri);
+ await setUpAppGateway(ctx, target.uri, {
+ telemetry,
+ targetPort,
+ targetProtocol,
+ });
}
export async function setUpAppGateway(
@@ -134,6 +140,10 @@ export async function setUpAppGateway(
* only for multi-port TCP apps.
*/
targetPort?: number;
+ /**
+ * targetProtocol is the protocol of the resource proxied by the gateway.
+ */
+ targetProtocol?: string;
}
) {
const rootClusterUri = routing.ensureRootClusterUri(targetUri);
@@ -146,6 +156,7 @@ export async function setUpAppGateway(
targetName: routing.parseAppUri(targetUri).params.appId,
targetUser: '',
targetSubresourceName: options.targetPort?.toString(),
+ targetProtocol: options.targetProtocol,
});
const connectionToReuse = ctx.connectionTracker.findConnectionByDocument(doc);
diff --git a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/documentsService.ts b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/documentsService.ts
index 5c586e828f31a..54c2d3da69fd4 100644
--- a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/documentsService.ts
+++ b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/documentsService.ts
@@ -142,6 +142,7 @@ export class DocumentsService {
port,
gatewayUri,
origin,
+ targetProtocol,
} = opts;
const uri = routing.getDocUri({ docId: unique() });
@@ -157,6 +158,7 @@ export class DocumentsService {
port,
origin,
status: '',
+ targetProtocol,
};
doc.title = getDocumentGatewayTitle(doc);
return doc;
diff --git a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/types.ts b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/types.ts
index 79a46587fbd65..279dce8aaf786 100644
--- a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/types.ts
+++ b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/types.ts
@@ -107,6 +107,10 @@ export interface DocumentGateway extends DocumentBase {
*/
port?: string;
origin: DocumentOrigin;
+ /**
+ * targetProtocol is the protocol of the resource proxied by the gateway.
+ */
+ targetProtocol?: string;
}
/**
@@ -326,6 +330,7 @@ export type CreateGatewayDocumentOpts = {
title?: string;
port?: string;
origin: DocumentOrigin;
+ targetProtocol?: string;
};
export type CreateAccessRequestDocumentOpts = {