Skip to content

Commit f6a7e03

Browse files
authored
feat: beautify mcp cli and add client selection (#123)
1 parent 0419a7d commit f6a7e03

2 files changed

Lines changed: 65 additions & 48 deletions

File tree

src/mcp.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,44 @@ export const runMCPInstall = async (options: {
1414
signup: boolean;
1515
region?: CloudRegion;
1616
}) => {
17-
clack.intro('Installing the PostHog MCP server.');
17+
clack.intro(chalk.bgGreenBright('Installing the PostHog MCP server'));
1818

1919
await addMCPServerToClientsStep({
2020
cloudRegion: options.region,
2121
askPermission: false,
2222
});
2323

24-
clack.outro(`${chalk.green(
25-
'You might need to restart your MCP clients to see the changes.',
26-
)}
24+
clack.log.message(
25+
`${chalk.greenBright(
26+
'You might need to restart your MCP clients to see the changes.',
27+
)}`,
28+
);
2729

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

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

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

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

44-
clack.outro(`PostHog MCP server removed from:
45-
${results.map((c) => `- ${c}`).join('\n ')}
46-
47-
${chalk.green(
48-
'You might need to restart your MCP clients to see the changes.',
49-
)}`);
48+
clack.log.success(`PostHog MCP server removed from:`);
49+
results.map((c) => clack.log.message(`- ${c}`));
50+
clack.outro(
51+
`${chalk.green(
52+
'You might need to restart your MCP clients to see the changes.\n\n',
53+
)}`,
54+
);
5055
};
5156

5257
export const getPersonalApiKey = async (options: {

src/steps/add-mcp-server-to-clients/index.ts

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ import type { Integration } from '../../lib/constants';
22
import { traceStep } from '../../telemetry';
33
import { analytics } from '../../utils/analytics';
44
import clack from '../../utils/clack';
5-
import {
6-
abort,
7-
abortIfCancelled,
8-
askForCloudRegion,
9-
} from '../../utils/clack-utils';
5+
import chalk from 'chalk';
6+
import { abortIfCancelled, askForCloudRegion } from '../../utils/clack-utils';
107
import { MCPClient } from './MCPClient';
118
import { CursorMCPClient } from './clients/cursor';
129
import { ClaudeMCPClient } from './clients/claude';
@@ -46,7 +43,7 @@ export const addMCPServerToClientsStep = async ({
4643
? await abortIfCancelled(
4744
clack.select({
4845
message:
49-
'Would you like to install the PostHog MCP server to use PostHog in your editor?',
46+
'Would you like to install the MCP server to use PostHog in your editor?',
5047
options: [
5148
{ value: true, label: 'Yes' },
5249
{ value: false, label: 'No' },
@@ -60,14 +57,33 @@ export const addMCPServerToClientsStep = async ({
6057
return [];
6158
}
6259

63-
const clients = await getSupportedClients();
60+
const supportedClients = await getSupportedClients();
61+
62+
const { multiselect } = await import('@clack/prompts');
63+
const selectedClientNames = await abortIfCancelled(
64+
multiselect({
65+
message: `Select which MCP clients to install the MCP server to: ${chalk.dim(
66+
'(Toggle: Space, Confirm: Enter, Toggle All: A, Cancel: CTRL + C)',
67+
)}`,
68+
options: supportedClients.map((client) => ({
69+
value: client.name,
70+
label: client.name,
71+
})),
72+
initialValues: supportedClients.map((client) => client.name),
73+
required: true,
74+
}),
75+
integration,
76+
);
77+
78+
const clients = supportedClients.filter((client) =>
79+
selectedClientNames.includes(client.name),
80+
);
6481

6582
const installedClients = await getInstalledClients();
6683

6784
if (installedClients.length > 0) {
6885
clack.log.warn(
69-
`The PostHog MCP server is already configured for:
70-
86+
`The MCP server is already configured for:
7187
${installedClients.map((c) => `- ${c.name}`).join('\n ')}`,
7288
);
7389

@@ -111,7 +127,7 @@ export const addMCPServerToClientsStep = async ({
111127
});
112128

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

@@ -139,40 +155,36 @@ export const removeMCPServerFromClientsStep = async ({
139155
return [];
140156
}
141157

142-
const removeServers: boolean = await abortIfCancelled(
143-
clack.select({
144-
message: `Found the PostHog MCP server in ${installedClients.length} clients. Would you like to remove it?`,
145-
options: [
146-
{
147-
value: true,
148-
label: 'Yes',
149-
hint: `Remove PostHog MCP server`,
150-
},
151-
{
152-
value: false,
153-
label: 'No',
154-
hint: 'Keep the MCP server configuration',
155-
},
156-
],
158+
const { multiselect } = await import('@clack/prompts');
159+
const selectedClientNames = await abortIfCancelled(
160+
multiselect({
161+
message: `Select which clients to remove the MCP server from: ${chalk.dim(
162+
'(Toggle: Space, Confirm: Enter, Toggle All: A, Cancel: CTRL + C)',
163+
)}`,
164+
options: installedClients.map((client) => ({
165+
value: client.name,
166+
label: client.name,
167+
})),
168+
initialValues: installedClients.map((client) => client.name),
157169
}),
158170
integration,
159171
);
160172

161-
if (!removeServers) {
173+
const clientsToRemove = installedClients.filter((client) =>
174+
selectedClientNames.includes(client.name),
175+
);
176+
177+
if (clientsToRemove.length === 0) {
162178
analytics.capture('wizard interaction', {
163-
action: 'declined to remove mcp servers',
164-
clients: installedClients.map((c) => c.name),
179+
action: 'no mcp servers selected for removal',
165180
integration,
166181
});
167-
168-
await abort('The MCP server was not removed.');
169182
return [];
170183
}
171184

172185
const results = await traceStep('removing mcp servers', async () => {
173-
await removeMCPServer(installedClients);
174-
175-
return installedClients.map((c) => c.name);
186+
await removeMCPServer(clientsToRemove);
187+
return clientsToRemove.map((c) => c.name);
176188
});
177189

178190
analytics.capture('wizard interaction', {

0 commit comments

Comments
 (0)