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
35 changes: 20 additions & 15 deletions src/mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,44 @@ export const runMCPInstall = async (options: {
signup: boolean;
region?: CloudRegion;
}) => {
clack.intro('Installing the PostHog MCP server.');
clack.intro(chalk.bgGreenBright('Installing the PostHog MCP server'));

await addMCPServerToClientsStep({
cloudRegion: options.region,
askPermission: false,
});

clack.outro(`${chalk.green(
'You might need to restart your MCP clients to see the changes.',
)}
clack.log.message(
`${chalk.greenBright(
'You might need to restart your MCP clients to see the changes.',
)}`,
);

Get started with some prompts like:
clack.log.message(`Get started with some prompts like:
- What feature flags do I have active?
- Add a new feature flag for our homepage redesign
- What are my most common errors?`);

- What feature flags do I have active?
- Add a new feature flag for our homepage redesign
- What are my most common errors?
`);
clack.log.message(`Check out our MCP Server documentation:
${chalk.blueBright(`https://posthog.com/docs/model-context-protocol`)}`);
};

export const runMCPRemove = async () => {
clack.intro(chalk.bgRed('Removing the PostHog MCP server'));
const results = await removeMCPServerFromClientsStep({});

if (results.length === 0) {
clack.outro(`No PostHog MCP servers found to remove.`);
return;
}

clack.outro(`PostHog MCP server removed from:
${results.map((c) => `- ${c}`).join('\n ')}

${chalk.green(
'You might need to restart your MCP clients to see the changes.',
)}`);
clack.log.success(`PostHog MCP server removed from:`);
results.map((c) => clack.log.message(`- ${c}`));
clack.outro(
`${chalk.green(
'You might need to restart your MCP clients to see the changes.\n\n',
)}`,
);
};

export const getPersonalApiKey = async (options: {
Expand Down
78 changes: 45 additions & 33 deletions src/steps/add-mcp-server-to-clients/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ import type { Integration } from '../../lib/constants';
import { traceStep } from '../../telemetry';
import { analytics } from '../../utils/analytics';
import clack from '../../utils/clack';
import {
abort,
abortIfCancelled,
askForCloudRegion,
} from '../../utils/clack-utils';
import chalk from 'chalk';
import { abortIfCancelled, askForCloudRegion } from '../../utils/clack-utils';
import { MCPClient } from './MCPClient';
import { CursorMCPClient } from './clients/cursor';
import { ClaudeMCPClient } from './clients/claude';
Expand Down Expand Up @@ -46,7 +43,7 @@ export const addMCPServerToClientsStep = async ({
? await abortIfCancelled(
clack.select({
message:
'Would you like to install the PostHog MCP server to use PostHog in your editor?',
'Would you like to install the MCP server to use PostHog in your editor?',
options: [
{ value: true, label: 'Yes' },
{ value: false, label: 'No' },
Expand All @@ -60,14 +57,33 @@ export const addMCPServerToClientsStep = async ({
return [];
}

const clients = await getSupportedClients();
const supportedClients = await getSupportedClients();

const { multiselect } = await import('@clack/prompts');
const selectedClientNames = await abortIfCancelled(
multiselect({
message: `Select which MCP clients to install the MCP server to: ${chalk.dim(
'(Toggle: Space, Confirm: Enter, Toggle All: A, Cancel: CTRL + C)',
)}`,
options: supportedClients.map((client) => ({
value: client.name,
label: client.name,
})),
initialValues: supportedClients.map((client) => client.name),
required: true,
}),
integration,
);

const clients = supportedClients.filter((client) =>
selectedClientNames.includes(client.name),
);

const installedClients = await getInstalledClients();

if (installedClients.length > 0) {
clack.log.warn(
`The PostHog MCP server is already configured for:

`The MCP server is already configured for:
${installedClients.map((c) => `- ${c.name}`).join('\n ')}`,
);

Expand Down Expand Up @@ -111,7 +127,7 @@ export const addMCPServerToClientsStep = async ({
});

clack.log.success(
`Added the PostHog MCP server to:
`Added the MCP server to:
${clients.map((c) => `- ${c.name}`).join('\n ')} `,
);

Expand Down Expand Up @@ -139,40 +155,36 @@ export const removeMCPServerFromClientsStep = async ({
return [];
}

const removeServers: boolean = await abortIfCancelled(
clack.select({
message: `Found the PostHog MCP server in ${installedClients.length} clients. Would you like to remove it?`,
options: [
{
value: true,
label: 'Yes',
hint: `Remove PostHog MCP server`,
},
{
value: false,
label: 'No',
hint: 'Keep the MCP server configuration',
},
],
const { multiselect } = await import('@clack/prompts');
const selectedClientNames = await abortIfCancelled(
multiselect({
message: `Select which clients to remove the MCP server from: ${chalk.dim(
'(Toggle: Space, Confirm: Enter, Toggle All: A, Cancel: CTRL + C)',
)}`,
options: installedClients.map((client) => ({
value: client.name,
label: client.name,
})),
initialValues: installedClients.map((client) => client.name),
}),
integration,
);

if (!removeServers) {
const clientsToRemove = installedClients.filter((client) =>
selectedClientNames.includes(client.name),
);

if (clientsToRemove.length === 0) {
analytics.capture('wizard interaction', {
action: 'declined to remove mcp servers',
clients: installedClients.map((c) => c.name),
action: 'no mcp servers selected for removal',
integration,
});

await abort('The MCP server was not removed.');
return [];
}

const results = await traceStep('removing mcp servers', async () => {
await removeMCPServer(installedClients);

return installedClients.map((c) => c.name);
await removeMCPServer(clientsToRemove);
return clientsToRemove.map((c) => c.name);
});

analytics.capture('wizard interaction', {
Expand Down
Loading