Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/insomnia/src/main/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ export enum SegmentEvent {
vcsSyncComplete = 'VCS Sync Completed',
vcsAction = 'VCS Action Executed',
buttonClick = 'Button Clicked',
mcpClientConnected = 'MCP Client Connected',
mcpClientDisconnected = 'MCP Client Disconnected',
mcpToolCalled = 'MCP Tool Called',
mcpResourceRead = 'MCP Resource Read',
mcpPromptCalled = 'MCP Prompt Called',
}

function hashString(input: string) {
Expand Down
32 changes: 32 additions & 0 deletions packages/insomnia/src/main/network/mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
METHOD_UNSUBSCRIBE_RESOURCE,
} from '~/common/mcp-utils';
import { generateId } from '~/common/misc';
import { SegmentEvent, trackSegmentEvent } from '~/main/analytics';
import { authorizeUserInDefaultBrowser } from '~/main/authorizeUserInDefaultBrowser';
import * as models from '~/models';
import { type McpRequest, TRANSPORT_TYPES, type TransportType } from '~/models/mcp-request';
Expand Down Expand Up @@ -861,6 +862,33 @@ const createTransportAndConnect = async (
// Use a longer timeout for initial connection to allow for auth flow to complete
await mcpClient.connect(transport, { timeout: 3 * 60 * 1000 });
}
const mcpRequest = await models.mcpRequest.getById(connectionOptions.requestId);
invariant(mcpRequest, 'MCP Request not found');

let authType = 'none';
if ('type' in mcpRequest.authentication) {
if (mcpRequest.authentication.type === 'oauth2') {
authType = 'oauth2-' + mcpRequest.authentication.grantType;
} else {
authType = mcpRequest.authentication.type;
}
}
const authDisabled = 'disabled' in mcpRequest.authentication && mcpRequest.authentication.disabled;
const isFirstConnection = !mcpRequest.connected;
trackSegmentEvent(SegmentEvent.mcpClientConnected, {
transportType: connectionOptions.transportType,
firstTime: isFirstConnection,
...(connectionOptions.transportType === TRANSPORT_TYPES.HTTP
? {
authType,
authDisabled,
}
: {}),
});
if (isFirstConnection) {
// Mark as connected for the first time
await models.mcpRequest.update(mcpRequest, { connected: true });
}
};

const openMcpClientConnection = async (options: OpenMcpClientConnectionOptions) => {
Expand Down Expand Up @@ -979,6 +1007,7 @@ const closeMcpConnection = async (options: CommonMcpOptions) => {
// Execute clear resource subscription in main process rather than UI to make sure closeAllMcpConnections method will clear subscriptions
await models.mcpRequest.clearResourceSubscriptions(requestId);
}
trackSegmentEvent(SegmentEvent.mcpClientDisconnected);
}
};

Expand Down Expand Up @@ -1020,6 +1049,7 @@ const callTool = async (options: CallToolOptions) => {
const mcpClient = _getMcpClient(requestId);
if (mcpClient) {
const response = await mcpClient.callTool({ name, arguments: parameters }, CompatibilityCallToolResultSchema);
trackSegmentEvent(SegmentEvent.mcpToolCalled);
return response.content;
}
return null;
Expand All @@ -1039,6 +1069,7 @@ const getPrompt = async (options: CommonMcpOptions & GetPromptRequest['params'])
const mcpClient = _getMcpClient(options.requestId);
if (mcpClient) {
const prompt = await mcpClient.getPrompt(params);
trackSegmentEvent(SegmentEvent.mcpPromptCalled);
return prompt;
}
return null;
Expand Down Expand Up @@ -1115,6 +1146,7 @@ const readResource = async (options: CommonMcpOptions & ReadResourceRequest['par
const mcpClient = _getMcpClient(requestId);
if (mcpClient) {
const resource = await mcpClient.readResource(params);
trackSegmentEvent(SegmentEvent.mcpResourceRead);
return resource;
}
return null;
Expand Down
2 changes: 2 additions & 0 deletions packages/insomnia/src/models/mcp-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface BaseMcpRequest {
mcpStdioAccess: boolean;
roots: Root[];
subscribeResources: string[];
connected: boolean;
}
export type McpServerPrimitiveTypes = 'tools' | 'resources' | 'prompts' | 'resourceTemplates';

Expand All @@ -53,6 +54,7 @@ export function init(): BaseMcpRequest {
mcpStdioAccess: false,
roots: [],
subscribeResources: [],
connected: false,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,7 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
const requestId = newMcpRequest._id;

window.main.trackSegmentEvent({
event: SegmentEvent.mcpClientRequestCreate,
properties: { transportType: 'streamable-http' },
event: SegmentEvent.mcpClientAdded,
});

return redirect(
Expand Down
2 changes: 1 addition & 1 deletion packages/insomnia/src/ui/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export enum SegmentEvent {
exportStarted = 'Export Started',
exportRequestsChosen = 'Export Requests Chosen',
mcpClientWorkspaceCreate = 'MCP Client Workspace Created',
mcpClientRequestCreate = 'MCP Client Request Created',
mcpClientAdded = 'MCP Client Added',
}

type PushPull = 'push' | 'pull';
Expand Down
Loading