@hubspot/cli 7.7.15-experimental.0 → 7.7.16-experimental.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/mcp/setup.d.ts +3 -9
- package/commands/mcp/setup.js +26 -220
- package/commands/mcp/start.d.ts +3 -9
- package/commands/mcp/start.js +15 -14
- package/commands/mcp.js +2 -1
- package/lang/en.d.ts +1 -0
- package/lang/en.js +1 -0
- package/lib/mcp/setup.d.ts +12 -0
- package/lib/mcp/setup.js +216 -0
- package/mcp-server/tools/project/AddFeatureToProject.js +6 -29
- package/mcp-server/tools/project/CreateProjectTool.js +7 -30
- package/mcp-server/tools/project/DeployProject.js +3 -10
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +3 -16
- package/mcp-server/tools/project/UploadProjectTools.js +2 -6
- package/mcp-server/utils/content.d.ts +3 -0
- package/mcp-server/utils/content.js +21 -0
- package/package.json +1 -1
package/commands/mcp/setup.d.ts
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { YargsCommandModule } from '../../types/Yargs';
|
|
2
2
|
interface MCPSetupArgs {
|
|
3
3
|
client?: string[];
|
|
4
4
|
addDocsSearch?: boolean;
|
|
5
5
|
}
|
|
6
|
-
declare
|
|
7
|
-
|
|
8
|
-
command: string[];
|
|
9
|
-
describe: undefined;
|
|
10
|
-
builder: (yargs: Argv) => Promise<Argv<{}>>;
|
|
11
|
-
handler: typeof handler;
|
|
12
|
-
};
|
|
13
|
-
export default _default;
|
|
6
|
+
declare const mcpSetupCommand: YargsCommandModule<unknown, MCPSetupArgs>;
|
|
7
|
+
export default mcpSetupCommand;
|
package/commands/mcp/setup.js
CHANGED
|
@@ -1,50 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const child_process_1 = require("child_process");
|
|
7
|
-
const util_1 = require("util");
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const fs_1 = __importDefault(require("fs"));
|
|
10
|
-
const os_1 = __importDefault(require("os"));
|
|
11
|
-
const SpinniesManager_1 = __importDefault(require("../../lib/ui/SpinniesManager"));
|
|
12
3
|
const exitCodes_1 = require("../../lib/enums/exitCodes");
|
|
13
|
-
const promptUtils_1 = require("../../lib/prompts/promptUtils");
|
|
14
4
|
const yargsUtils_1 = require("../../lib/yargsUtils");
|
|
15
5
|
const en_1 = require("../../lang/en");
|
|
16
|
-
const errorHandlers_1 = require("../../lib/errorHandlers");
|
|
17
6
|
const logger_1 = require("../../lib/ui/logger");
|
|
7
|
+
const setup_1 = require("../../lib/mcp/setup");
|
|
18
8
|
const command = ['setup', 'update'];
|
|
19
9
|
const describe = undefined; // Leave hidden for now
|
|
20
|
-
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
21
|
-
const claudeCode = 'claude';
|
|
22
|
-
const windsurf = 'windsurf';
|
|
23
|
-
const cursor = 'cursor';
|
|
24
|
-
const mcpServerName = 'hubspot-cli-mcp';
|
|
25
|
-
const supportedMintlifyClients = [windsurf, cursor];
|
|
26
|
-
const supportedTools = [
|
|
27
|
-
{ name: en_1.commands.mcp.setup.claudeCode, value: claudeCode },
|
|
28
|
-
{ name: en_1.commands.mcp.setup.cursor, value: cursor },
|
|
29
|
-
{ name: en_1.commands.mcp.setup.windsurf, value: windsurf },
|
|
30
|
-
];
|
|
31
|
-
const hsCommand = 'hs';
|
|
32
|
-
const mcpCommandArgs = ['mcp', 'start'];
|
|
33
|
-
function setupBuilder(yargs) {
|
|
34
|
-
yargs
|
|
35
|
-
.option('client', {
|
|
36
|
-
describe: en_1.commands.mcp.setup.args.client,
|
|
37
|
-
type: 'array',
|
|
38
|
-
choices: [...supportedTools.map(tool => tool.value)],
|
|
39
|
-
})
|
|
40
|
-
.option('add-docs-search', {
|
|
41
|
-
type: 'boolean',
|
|
42
|
-
});
|
|
43
|
-
return yargs;
|
|
44
|
-
}
|
|
45
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(setupBuilder, command, describe, {
|
|
46
|
-
useGlobalOptions: true,
|
|
47
|
-
});
|
|
48
10
|
async function handler(args) {
|
|
49
11
|
try {
|
|
50
12
|
await import('@modelcontextprotocol/sdk/server/mcp.js');
|
|
@@ -53,192 +15,36 @@ async function handler(args) {
|
|
|
53
15
|
logger_1.uiLogger.error(en_1.commands.mcp.setup.errors.needsNode20);
|
|
54
16
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
55
17
|
}
|
|
56
|
-
const derivedTargets = await addMcpServerToConfig(args.client);
|
|
57
|
-
if (args.addDocsSearch) {
|
|
58
|
-
logger_1.uiLogger.info(en_1.commands.mcp.setup.installingDocSearch);
|
|
59
|
-
logger_1.uiLogger.log('');
|
|
60
|
-
await new Promise(() => {
|
|
61
|
-
const subcommands = ['mint-mcp', 'add', 'hubspot-migration'];
|
|
62
|
-
const docsSearchClients = derivedTargets.filter(target => supportedMintlifyClients.includes(target));
|
|
63
|
-
const childProcess = (0, child_process_1.spawn)(`npx`, docsSearchClients && docsSearchClients.length
|
|
64
|
-
? [...subcommands, '--client', ...docsSearchClients]
|
|
65
|
-
: subcommands, {
|
|
66
|
-
stdio: 'inherit',
|
|
67
|
-
});
|
|
68
|
-
childProcess.on('exit', code => {
|
|
69
|
-
if (code !== 0) {
|
|
70
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
71
|
-
}
|
|
72
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
77
|
-
}
|
|
78
|
-
async function addMcpServerToConfig(targets) {
|
|
79
18
|
try {
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
name: 'selectedTargets',
|
|
84
|
-
type: 'checkbox',
|
|
85
|
-
message: en_1.commands.mcp.setup.prompts.targets,
|
|
86
|
-
choices: supportedTools,
|
|
87
|
-
validate: (choices) => {
|
|
88
|
-
return choices.length === 0
|
|
89
|
-
? en_1.commands.mcp.setup.prompts.targetsRequired
|
|
90
|
-
: true;
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
derivedTargets = selectedTargets;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
derivedTargets = targets;
|
|
97
|
-
}
|
|
98
|
-
SpinniesManager_1.default.init();
|
|
99
|
-
if (derivedTargets.includes(claudeCode)) {
|
|
100
|
-
await runSetupFunction(setupClaudeCode);
|
|
101
|
-
}
|
|
102
|
-
if (derivedTargets.includes(cursor)) {
|
|
103
|
-
await runSetupFunction(setupCursor);
|
|
19
|
+
const derivedTargets = await (0, setup_1.addMcpServerToConfig)(args.client);
|
|
20
|
+
if (args.addDocsSearch) {
|
|
21
|
+
await (0, setup_1.addMintlifyMcpServer)(derivedTargets);
|
|
104
22
|
}
|
|
105
|
-
if (derivedTargets.includes(windsurf)) {
|
|
106
|
-
await runSetupFunction(setupWindsurf);
|
|
107
|
-
}
|
|
108
|
-
logger_1.uiLogger.info(en_1.commands.mcp.setup.success(derivedTargets));
|
|
109
|
-
return derivedTargets;
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
SpinniesManager_1.default.fail('mcpSetup', {
|
|
113
|
-
text: en_1.commands.mcp.setup.spinners.failedToConfigure,
|
|
114
|
-
});
|
|
115
|
-
(0, errorHandlers_1.logError)(error);
|
|
116
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
117
23
|
}
|
|
118
|
-
|
|
119
|
-
async function runSetupFunction(func) {
|
|
120
|
-
const result = await func();
|
|
121
|
-
if (!result) {
|
|
24
|
+
catch (e) {
|
|
122
25
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
123
26
|
}
|
|
27
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
124
28
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
});
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
let mcpConfig = {};
|
|
138
|
-
try {
|
|
139
|
-
const configContent = fs_1.default.readFileSync(config.configPath, 'utf8');
|
|
140
|
-
mcpConfig = JSON.parse(configContent);
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
SpinniesManager_1.default.fail('spinner', {
|
|
144
|
-
text: config.failedMessage,
|
|
145
|
-
});
|
|
146
|
-
(0, errorHandlers_1.logError)(error);
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
// Initialize mcpServers if it doesn't exist
|
|
150
|
-
if (!mcpConfig.mcpServers) {
|
|
151
|
-
mcpConfig.mcpServers = {};
|
|
152
|
-
}
|
|
153
|
-
// Add or update HubSpot CLI MCP server
|
|
154
|
-
mcpConfig.mcpServers[mcpServerName] = {
|
|
155
|
-
command: hsCommand,
|
|
156
|
-
args: mcpCommandArgs,
|
|
157
|
-
};
|
|
158
|
-
// Write the updated config
|
|
159
|
-
fs_1.default.writeFileSync(config.configPath, JSON.stringify(mcpConfig, null, 2));
|
|
160
|
-
SpinniesManager_1.default.succeed('spinner', {
|
|
161
|
-
text: config.configuredMessage,
|
|
162
|
-
});
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
SpinniesManager_1.default.fail('spinner', {
|
|
167
|
-
text: config.failedMessage,
|
|
168
|
-
});
|
|
169
|
-
(0, errorHandlers_1.logError)(error);
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async function setupClaudeCode() {
|
|
174
|
-
try {
|
|
175
|
-
SpinniesManager_1.default.add('claudeCode', {
|
|
176
|
-
text: en_1.commands.mcp.setup.spinners.configuringClaudeCode,
|
|
177
|
-
});
|
|
178
|
-
try {
|
|
179
|
-
// Check if claude command is available
|
|
180
|
-
await execAsync('claude --version');
|
|
181
|
-
// Run claude mcp add command
|
|
182
|
-
const mcpConfig = JSON.stringify({
|
|
183
|
-
type: 'stdio',
|
|
184
|
-
command: hsCommand,
|
|
185
|
-
args: mcpCommandArgs,
|
|
186
|
-
});
|
|
187
|
-
const { stdout } = await execAsync('claude mcp list');
|
|
188
|
-
if (stdout.includes(mcpServerName)) {
|
|
189
|
-
SpinniesManager_1.default.update('claudeCode', {
|
|
190
|
-
text: en_1.commands.mcp.setup.spinners.alreadyInstalled,
|
|
191
|
-
});
|
|
192
|
-
await execAsync(`claude mcp remove "${mcpServerName}" --scope user`);
|
|
193
|
-
}
|
|
194
|
-
await execAsync(`claude mcp add-json "${mcpServerName}" '${mcpConfig}' --scope user`);
|
|
195
|
-
SpinniesManager_1.default.succeed('claudeCode', {
|
|
196
|
-
text: en_1.commands.mcp.setup.spinners.configuredClaudeCode,
|
|
197
|
-
});
|
|
198
|
-
return true;
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
if (error instanceof Error &&
|
|
202
|
-
error.message.includes('claude: command not found')) {
|
|
203
|
-
SpinniesManager_1.default.fail('claudeCode', {
|
|
204
|
-
text: en_1.commands.mcp.setup.spinners.claudeCodeNotFound,
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
SpinniesManager_1.default.fail('claudeCode', {
|
|
209
|
-
text: en_1.commands.mcp.setup.spinners.claudeCodeInstallFailed,
|
|
210
|
-
});
|
|
211
|
-
(0, errorHandlers_1.logError)(error);
|
|
212
|
-
}
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
catch (error) {
|
|
217
|
-
SpinniesManager_1.default.fail('claudeCode', {
|
|
218
|
-
text: en_1.commands.mcp.setup.spinners.claudeCodeInstallFailed,
|
|
219
|
-
});
|
|
220
|
-
(0, errorHandlers_1.logError)(error);
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
function setupCursor() {
|
|
225
|
-
const cursorConfigPath = path_1.default.join(os_1.default.homedir(), '.cursor', 'mcp.json');
|
|
226
|
-
return setupMcpConfigFile({
|
|
227
|
-
configPath: cursorConfigPath,
|
|
228
|
-
configuringMessage: en_1.commands.mcp.setup.spinners.configuringCursor,
|
|
229
|
-
configuredMessage: en_1.commands.mcp.setup.spinners.configuredCursor,
|
|
230
|
-
failedMessage: en_1.commands.mcp.setup.spinners.failedToConfigureCursor,
|
|
231
|
-
configMissingMessage: en_1.commands.mcp.setup.spinners.noCursorMcpFile(cursorConfigPath),
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
function setupWindsurf() {
|
|
235
|
-
const windsurfConfigPath = path_1.default.join(os_1.default.homedir(), '.codeium', 'windsurf', 'mcp_config.json');
|
|
236
|
-
return setupMcpConfigFile({
|
|
237
|
-
configPath: windsurfConfigPath,
|
|
238
|
-
configuringMessage: en_1.commands.mcp.setup.spinners.configuringWindsurf,
|
|
239
|
-
configuredMessage: en_1.commands.mcp.setup.spinners.configuredWindsurf,
|
|
240
|
-
failedMessage: en_1.commands.mcp.setup.spinners.failedToConfigureWindsurf,
|
|
241
|
-
configMissingMessage: en_1.commands.mcp.setup.spinners.noWindsurfFile(windsurfConfigPath),
|
|
29
|
+
function setupBuilder(yargs) {
|
|
30
|
+
yargs
|
|
31
|
+
.option('client', {
|
|
32
|
+
describe: en_1.commands.mcp.setup.args.client,
|
|
33
|
+
type: 'array',
|
|
34
|
+
choices: [...setup_1.supportedTools.map(tool => tool.value)],
|
|
35
|
+
})
|
|
36
|
+
.option('add-docs-search', {
|
|
37
|
+
type: 'boolean',
|
|
242
38
|
});
|
|
39
|
+
return yargs;
|
|
243
40
|
}
|
|
244
|
-
|
|
41
|
+
const builder = (0, yargsUtils_1.makeYargsBuilder)(setupBuilder, command, describe, {
|
|
42
|
+
useGlobalOptions: true,
|
|
43
|
+
});
|
|
44
|
+
const mcpSetupCommand = {
|
|
45
|
+
command,
|
|
46
|
+
describe,
|
|
47
|
+
handler,
|
|
48
|
+
builder,
|
|
49
|
+
};
|
|
50
|
+
exports.default = mcpSetupCommand;
|
package/commands/mcp/start.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare
|
|
3
|
-
|
|
4
|
-
command: string;
|
|
5
|
-
describe: undefined;
|
|
6
|
-
builder: (yargs: Argv) => Promise<Argv<{}>>;
|
|
7
|
-
handler: typeof handler;
|
|
8
|
-
};
|
|
9
|
-
export default _default;
|
|
1
|
+
import { YargsCommandModule } from '../../types/Yargs';
|
|
2
|
+
declare const mcpStartCommand: YargsCommandModule<unknown, unknown>;
|
|
3
|
+
export default mcpStartCommand;
|
package/commands/mcp/start.js
CHANGED
|
@@ -11,14 +11,9 @@ const yargsUtils_1 = require("../../lib/yargsUtils");
|
|
|
11
11
|
const logger_1 = require("../../lib/ui/logger");
|
|
12
12
|
const errorHandlers_1 = require("../../lib/errorHandlers");
|
|
13
13
|
const en_1 = require("../../lang/en");
|
|
14
|
+
const process_1 = require("../../lib/process");
|
|
14
15
|
const command = 'start';
|
|
15
16
|
const describe = undefined; // Leave hidden for now
|
|
16
|
-
function startBuilder(yargs) {
|
|
17
|
-
return yargs;
|
|
18
|
-
}
|
|
19
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(startBuilder, command, describe, {
|
|
20
|
-
useGlobalOptions: true,
|
|
21
|
-
});
|
|
22
17
|
async function handler() {
|
|
23
18
|
try {
|
|
24
19
|
await import('@modelcontextprotocol/sdk/server/mcp.js');
|
|
@@ -54,13 +49,7 @@ async function startMcpServer() {
|
|
|
54
49
|
child.on('close', () => {
|
|
55
50
|
logger_1.uiLogger.info(en_1.commands.mcp.start.stoppedSuccessfully);
|
|
56
51
|
});
|
|
57
|
-
|
|
58
|
-
process.on('SIGINT', () => {
|
|
59
|
-
logger_1.uiLogger.info(en_1.commands.mcp.start.shuttingDown);
|
|
60
|
-
child.kill('SIGTERM');
|
|
61
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
62
|
-
});
|
|
63
|
-
process.on('SIGTERM', () => {
|
|
52
|
+
(0, process_1.handleExit)(() => {
|
|
64
53
|
logger_1.uiLogger.info(en_1.commands.mcp.start.shuttingDown);
|
|
65
54
|
child.kill('SIGTERM');
|
|
66
55
|
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
@@ -71,4 +60,16 @@ async function startMcpServer() {
|
|
|
71
60
|
(0, errorHandlers_1.logError)(error);
|
|
72
61
|
}
|
|
73
62
|
}
|
|
74
|
-
|
|
63
|
+
function startBuilder(yargs) {
|
|
64
|
+
return yargs;
|
|
65
|
+
}
|
|
66
|
+
const builder = (0, yargsUtils_1.makeYargsBuilder)(startBuilder, command, describe, {
|
|
67
|
+
useGlobalOptions: true,
|
|
68
|
+
});
|
|
69
|
+
const mcpStartCommand = {
|
|
70
|
+
command,
|
|
71
|
+
describe,
|
|
72
|
+
handler,
|
|
73
|
+
builder,
|
|
74
|
+
};
|
|
75
|
+
exports.default = mcpStartCommand;
|
package/commands/mcp.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const start_1 = __importDefault(require("./mcp/start"));
|
|
7
7
|
const setup_1 = __importDefault(require("./mcp/setup"));
|
|
8
8
|
const yargsUtils_1 = require("../lib/yargsUtils");
|
|
9
|
+
const en_1 = require("../lang/en");
|
|
9
10
|
const command = 'mcp';
|
|
10
11
|
// Leave this as undefined to hide the command
|
|
11
12
|
const describe = undefined;
|
|
@@ -13,7 +14,7 @@ function mcpBuilder(yargs) {
|
|
|
13
14
|
yargs.command(start_1.default).command(setup_1.default).demandCommand(1, '');
|
|
14
15
|
return yargs;
|
|
15
16
|
}
|
|
16
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(mcpBuilder, command, describe, {
|
|
17
|
+
const builder = (0, yargsUtils_1.makeYargsBuilder)(mcpBuilder, command, en_1.commands.mcp.describe, {
|
|
17
18
|
useGlobalOptions: true,
|
|
18
19
|
});
|
|
19
20
|
const mcpCommand = {
|
package/lang/en.d.ts
CHANGED
|
@@ -765,6 +765,7 @@ Global configuration replaces hubspot.config.yml, and you will be prompted to mi
|
|
|
765
765
|
readonly tailLogs: (functionPath: string, accountId: string) => string;
|
|
766
766
|
};
|
|
767
767
|
readonly mcp: {
|
|
768
|
+
readonly describe: "Commands for managing HubSpot MCP servers";
|
|
768
769
|
readonly setup: {
|
|
769
770
|
readonly installingDocSearch: "Adding the docs-search mcp server";
|
|
770
771
|
readonly claudeCode: "Claude Code";
|
package/lang/en.js
CHANGED
|
@@ -777,6 +777,7 @@ exports.commands = {
|
|
|
777
777
|
tailLogs: (functionPath, accountId) => `Waiting for log entries for "${functionPath}" on account "${accountId}".\n`,
|
|
778
778
|
},
|
|
779
779
|
mcp: {
|
|
780
|
+
describe: 'Commands for managing HubSpot MCP servers',
|
|
780
781
|
setup: {
|
|
781
782
|
installingDocSearch: 'Adding the docs-search mcp server',
|
|
782
783
|
claudeCode: 'Claude Code',
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const supportedTools: ({
|
|
2
|
+
name: "Claude Code";
|
|
3
|
+
value: string;
|
|
4
|
+
} | {
|
|
5
|
+
name: "Cursor";
|
|
6
|
+
value: string;
|
|
7
|
+
} | {
|
|
8
|
+
name: "Windsurf";
|
|
9
|
+
value: string;
|
|
10
|
+
})[];
|
|
11
|
+
export declare function addMintlifyMcpServer(installTargets: string[]): Promise<void>;
|
|
12
|
+
export declare function addMcpServerToConfig(targets: string[] | undefined): Promise<string[]>;
|
package/lib/mcp/setup.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.supportedTools = void 0;
|
|
7
|
+
exports.addMintlifyMcpServer = addMintlifyMcpServer;
|
|
8
|
+
exports.addMcpServerToConfig = addMcpServerToConfig;
|
|
9
|
+
const logger_1 = require("../ui/logger");
|
|
10
|
+
const en_1 = require("../../lang/en");
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
12
|
+
const promptUtils_1 = require("../prompts/promptUtils");
|
|
13
|
+
const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
|
|
14
|
+
const errorHandlers_1 = require("../errorHandlers");
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const command_1 = require("../../mcp-server/utils/command");
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const os_1 = __importDefault(require("os"));
|
|
19
|
+
const mcpServerName = 'hubspot-cli-mcp';
|
|
20
|
+
const claudeCode = 'claude';
|
|
21
|
+
const windsurf = 'windsurf';
|
|
22
|
+
const cursor = 'cursor';
|
|
23
|
+
const supportedMintlifyClients = [windsurf, cursor];
|
|
24
|
+
exports.supportedTools = [
|
|
25
|
+
{ name: en_1.commands.mcp.setup.claudeCode, value: claudeCode },
|
|
26
|
+
{ name: en_1.commands.mcp.setup.cursor, value: cursor },
|
|
27
|
+
{ name: en_1.commands.mcp.setup.windsurf, value: windsurf },
|
|
28
|
+
];
|
|
29
|
+
const hsCommand = 'hs';
|
|
30
|
+
const mcpCommandArgs = ['mcp', 'start'];
|
|
31
|
+
async function addMintlifyMcpServer(installTargets) {
|
|
32
|
+
await runSetupFunction(() => setupMintlify(installTargets));
|
|
33
|
+
}
|
|
34
|
+
async function setupMintlify(derivedTargets) {
|
|
35
|
+
logger_1.uiLogger.info(en_1.commands.mcp.setup.installingDocSearch);
|
|
36
|
+
logger_1.uiLogger.log('');
|
|
37
|
+
return new Promise(resolve => {
|
|
38
|
+
const subcommands = ['mint-mcp', 'add', 'hubspot-migration'];
|
|
39
|
+
const docsSearchClients = derivedTargets.filter(target => supportedMintlifyClients.includes(target));
|
|
40
|
+
const childProcess = (0, child_process_1.spawn)(`npx`, docsSearchClients && docsSearchClients.length
|
|
41
|
+
? [...subcommands, '--client', ...docsSearchClients]
|
|
42
|
+
: subcommands, {
|
|
43
|
+
stdio: 'inherit',
|
|
44
|
+
});
|
|
45
|
+
childProcess.on('exit', code => {
|
|
46
|
+
if (code !== 0) {
|
|
47
|
+
resolve(false);
|
|
48
|
+
}
|
|
49
|
+
resolve(true);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async function addMcpServerToConfig(targets) {
|
|
54
|
+
try {
|
|
55
|
+
let derivedTargets = [];
|
|
56
|
+
if (!targets || targets.length === 0) {
|
|
57
|
+
const { selectedTargets } = await (0, promptUtils_1.promptUser)({
|
|
58
|
+
name: 'selectedTargets',
|
|
59
|
+
type: 'checkbox',
|
|
60
|
+
message: en_1.commands.mcp.setup.prompts.targets,
|
|
61
|
+
choices: exports.supportedTools,
|
|
62
|
+
validate: (choices) => {
|
|
63
|
+
return choices.length === 0
|
|
64
|
+
? en_1.commands.mcp.setup.prompts.targetsRequired
|
|
65
|
+
: true;
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
derivedTargets = selectedTargets;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
derivedTargets = targets;
|
|
72
|
+
}
|
|
73
|
+
SpinniesManager_1.default.init();
|
|
74
|
+
if (derivedTargets.includes(claudeCode)) {
|
|
75
|
+
await runSetupFunction(setupClaudeCode);
|
|
76
|
+
}
|
|
77
|
+
if (derivedTargets.includes(cursor)) {
|
|
78
|
+
await runSetupFunction(setupCursor);
|
|
79
|
+
}
|
|
80
|
+
if (derivedTargets.includes(windsurf)) {
|
|
81
|
+
await runSetupFunction(setupWindsurf);
|
|
82
|
+
}
|
|
83
|
+
logger_1.uiLogger.info(en_1.commands.mcp.setup.success(derivedTargets));
|
|
84
|
+
return derivedTargets;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
SpinniesManager_1.default.fail('mcpSetup', {
|
|
88
|
+
text: en_1.commands.mcp.setup.spinners.failedToConfigure,
|
|
89
|
+
});
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function runSetupFunction(func) {
|
|
94
|
+
const result = await func();
|
|
95
|
+
if (!result) {
|
|
96
|
+
throw new Error();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function setupMcpConfigFile(config) {
|
|
100
|
+
try {
|
|
101
|
+
SpinniesManager_1.default.add('spinner', {
|
|
102
|
+
text: config.configuringMessage,
|
|
103
|
+
});
|
|
104
|
+
if (!fs_1.default.existsSync(config.configPath)) {
|
|
105
|
+
SpinniesManager_1.default.fail('spinner', {
|
|
106
|
+
text: config.configMissingMessage,
|
|
107
|
+
});
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
let mcpConfig = {};
|
|
111
|
+
try {
|
|
112
|
+
const configContent = fs_1.default.readFileSync(config.configPath, 'utf8');
|
|
113
|
+
mcpConfig = JSON.parse(configContent);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
SpinniesManager_1.default.fail('spinner', {
|
|
117
|
+
text: config.failedMessage,
|
|
118
|
+
});
|
|
119
|
+
(0, errorHandlers_1.logError)(error);
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
// Initialize mcpServers if it doesn't exist
|
|
123
|
+
if (!mcpConfig.mcpServers) {
|
|
124
|
+
mcpConfig.mcpServers = {};
|
|
125
|
+
}
|
|
126
|
+
// Add or update HubSpot CLI MCP server
|
|
127
|
+
mcpConfig.mcpServers[mcpServerName] = {
|
|
128
|
+
command: hsCommand,
|
|
129
|
+
args: mcpCommandArgs,
|
|
130
|
+
};
|
|
131
|
+
// Write the updated config
|
|
132
|
+
fs_1.default.writeFileSync(config.configPath, JSON.stringify(mcpConfig, null, 2));
|
|
133
|
+
SpinniesManager_1.default.succeed('spinner', {
|
|
134
|
+
text: config.configuredMessage,
|
|
135
|
+
});
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
SpinniesManager_1.default.fail('spinner', {
|
|
140
|
+
text: config.failedMessage,
|
|
141
|
+
});
|
|
142
|
+
(0, errorHandlers_1.logError)(error);
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function setupClaudeCode() {
|
|
147
|
+
try {
|
|
148
|
+
SpinniesManager_1.default.add('claudeCode', {
|
|
149
|
+
text: en_1.commands.mcp.setup.spinners.configuringClaudeCode,
|
|
150
|
+
});
|
|
151
|
+
try {
|
|
152
|
+
// Check if claude command is available
|
|
153
|
+
await (0, command_1.execAsync)('claude --version');
|
|
154
|
+
// Run claude mcp add command
|
|
155
|
+
const mcpConfig = JSON.stringify({
|
|
156
|
+
type: 'stdio',
|
|
157
|
+
command: hsCommand,
|
|
158
|
+
args: mcpCommandArgs,
|
|
159
|
+
});
|
|
160
|
+
const { stdout } = await (0, command_1.execAsync)('claude mcp list');
|
|
161
|
+
if (stdout.includes(mcpServerName)) {
|
|
162
|
+
SpinniesManager_1.default.update('claudeCode', {
|
|
163
|
+
text: en_1.commands.mcp.setup.spinners.alreadyInstalled,
|
|
164
|
+
});
|
|
165
|
+
await (0, command_1.execAsync)(`claude mcp remove "${mcpServerName}" --scope user`);
|
|
166
|
+
}
|
|
167
|
+
await (0, command_1.execAsync)(`claude mcp add-json "${mcpServerName}" '${mcpConfig}' --scope user`);
|
|
168
|
+
SpinniesManager_1.default.succeed('claudeCode', {
|
|
169
|
+
text: en_1.commands.mcp.setup.spinners.configuredClaudeCode,
|
|
170
|
+
});
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
if (error instanceof Error &&
|
|
175
|
+
error.message.includes('claude: command not found')) {
|
|
176
|
+
SpinniesManager_1.default.fail('claudeCode', {
|
|
177
|
+
text: en_1.commands.mcp.setup.spinners.claudeCodeNotFound,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
SpinniesManager_1.default.fail('claudeCode', {
|
|
182
|
+
text: en_1.commands.mcp.setup.spinners.claudeCodeInstallFailed,
|
|
183
|
+
});
|
|
184
|
+
(0, errorHandlers_1.logError)(error);
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
SpinniesManager_1.default.fail('claudeCode', {
|
|
191
|
+
text: en_1.commands.mcp.setup.spinners.claudeCodeInstallFailed,
|
|
192
|
+
});
|
|
193
|
+
(0, errorHandlers_1.logError)(error);
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function setupCursor() {
|
|
198
|
+
const cursorConfigPath = path_1.default.join(os_1.default.homedir(), '.cursor', 'mcp.json');
|
|
199
|
+
return setupMcpConfigFile({
|
|
200
|
+
configPath: cursorConfigPath,
|
|
201
|
+
configuringMessage: en_1.commands.mcp.setup.spinners.configuringCursor,
|
|
202
|
+
configuredMessage: en_1.commands.mcp.setup.spinners.configuredCursor,
|
|
203
|
+
failedMessage: en_1.commands.mcp.setup.spinners.failedToConfigureCursor,
|
|
204
|
+
configMissingMessage: en_1.commands.mcp.setup.spinners.noCursorMcpFile(cursorConfigPath),
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
function setupWindsurf() {
|
|
208
|
+
const windsurfConfigPath = path_1.default.join(os_1.default.homedir(), '.codeium', 'windsurf', 'mcp_config.json');
|
|
209
|
+
return setupMcpConfigFile({
|
|
210
|
+
configPath: windsurfConfigPath,
|
|
211
|
+
configuringMessage: en_1.commands.mcp.setup.spinners.configuringWindsurf,
|
|
212
|
+
configuredMessage: en_1.commands.mcp.setup.spinners.configuredWindsurf,
|
|
213
|
+
failedMessage: en_1.commands.mcp.setup.spinners.failedToConfigureWindsurf,
|
|
214
|
+
configMissingMessage: en_1.commands.mcp.setup.spinners.noWindsurfFile(windsurfConfigPath),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
@@ -7,11 +7,12 @@ const constants_1 = require("../../../lib/constants");
|
|
|
7
7
|
const command_1 = require("../../utils/command");
|
|
8
8
|
const constants_2 = require("./constants");
|
|
9
9
|
const project_1 = require("../../utils/project");
|
|
10
|
+
const content_1 = require("../../utils/content");
|
|
10
11
|
const inputSchema = {
|
|
11
12
|
absoluteProjectPath: constants_2.absoluteProjectPath,
|
|
12
13
|
addApp: zod_1.z
|
|
13
14
|
.boolean()
|
|
14
|
-
.describe('Should an app be added? If there is no app in the project,
|
|
15
|
+
.describe('Should an app be added? If there is no app in the project, an app must be added to add a feature'),
|
|
15
16
|
distribution: zod_1.z
|
|
16
17
|
.optional(zod_1.z.union([
|
|
17
18
|
zod_1.z.literal(constants_1.APP_DISTRIBUTION_TYPES.MARKETPLACE),
|
|
@@ -51,19 +52,13 @@ class AddFeatureToProject extends types_1.Tool {
|
|
|
51
52
|
command = (0, command_1.addFlag)(command, 'distribution', distribution);
|
|
52
53
|
}
|
|
53
54
|
else if (addApp) {
|
|
54
|
-
content.push({
|
|
55
|
-
type: 'text',
|
|
56
|
-
text: `Ask the user how they would you like to distribute the application? Options are ${constants_1.APP_DISTRIBUTION_TYPES.MARKETPLACE} and ${constants_1.APP_DISTRIBUTION_TYPES.PRIVATE}`,
|
|
57
|
-
});
|
|
55
|
+
content.push((0, content_1.formatTextContent)(`Ask the user how they would you like to distribute the application. Options are ${constants_1.APP_DISTRIBUTION_TYPES.MARKETPLACE} and ${constants_1.APP_DISTRIBUTION_TYPES.PRIVATE}`));
|
|
58
56
|
}
|
|
59
57
|
if (auth) {
|
|
60
58
|
command = (0, command_1.addFlag)(command, 'auth', auth);
|
|
61
59
|
}
|
|
62
60
|
else if (addApp) {
|
|
63
|
-
content.push({
|
|
64
|
-
type: 'text',
|
|
65
|
-
text: `Ask the user which auth type they would like to use? Options are ${constants_1.APP_AUTH_TYPES.STATIC} and ${constants_1.APP_AUTH_TYPES.OAUTH}`,
|
|
66
|
-
});
|
|
61
|
+
content.push((0, content_1.formatTextContent)(`Ask the user which auth type they would like to use. Options are ${constants_1.APP_AUTH_TYPES.STATIC} and ${constants_1.APP_AUTH_TYPES.OAUTH}`));
|
|
67
62
|
}
|
|
68
63
|
if (content.length > 0) {
|
|
69
64
|
return {
|
|
@@ -73,28 +68,10 @@ class AddFeatureToProject extends types_1.Tool {
|
|
|
73
68
|
// If features isn't provided, pass an empty array to bypass the prompt
|
|
74
69
|
command = (0, command_1.addFlag)(command, 'features', features || []);
|
|
75
70
|
const { stdout, stderr } = await (0, project_1.runCommandInDir)(absoluteProjectPath, command);
|
|
76
|
-
return
|
|
77
|
-
content: [
|
|
78
|
-
{
|
|
79
|
-
type: 'text',
|
|
80
|
-
text: stdout,
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
type: 'text',
|
|
84
|
-
text: stderr,
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
|
-
};
|
|
71
|
+
return (0, content_1.formatTextContents)(stdout, stderr);
|
|
88
72
|
}
|
|
89
73
|
catch (error) {
|
|
90
|
-
return {
|
|
91
|
-
content: [
|
|
92
|
-
{
|
|
93
|
-
type: 'text',
|
|
94
|
-
text: error instanceof Error ? error.message : `${error}`,
|
|
95
|
-
},
|
|
96
|
-
],
|
|
97
|
-
};
|
|
74
|
+
return (0, content_1.formatTextContents)(error instanceof Error ? error.message : `${error}`);
|
|
98
75
|
}
|
|
99
76
|
}
|
|
100
77
|
register() {
|
|
@@ -8,6 +8,7 @@ const command_1 = require("../../utils/command");
|
|
|
8
8
|
const v3_1 = require("../../../lib/projects/create/v3");
|
|
9
9
|
const constants_2 = require("./constants");
|
|
10
10
|
const project_1 = require("../../utils/project");
|
|
11
|
+
const content_1 = require("../../utils/content");
|
|
11
12
|
const inputSchema = {
|
|
12
13
|
absoluteCurrentWorkingDirectory: constants_2.absoluteCurrentWorkingDirectory,
|
|
13
14
|
name: zod_1.z
|
|
@@ -15,10 +16,10 @@ const inputSchema = {
|
|
|
15
16
|
.describe('The name of the project to be created. This name is how your project will appear in HubSpot.'),
|
|
16
17
|
destination: zod_1.z
|
|
17
18
|
.string()
|
|
18
|
-
.describe('Relative path to the directory the project will be created in.
|
|
19
|
+
.describe('Relative path to the directory the project will be created in. DO NOT use the current directory unless the user has explicitly stated to do so.'),
|
|
19
20
|
projectBase: zod_1.z
|
|
20
21
|
.union([zod_1.z.literal(v3_1.EMPTY_PROJECT), zod_1.z.literal(v3_1.PROJECT_WITH_APP)])
|
|
21
|
-
.describe('Empty will create
|
|
22
|
+
.describe('Empty will create an empty project, and app will create a project with an app inside of it.'),
|
|
22
23
|
distribution: zod_1.z
|
|
23
24
|
.optional(zod_1.z.union([
|
|
24
25
|
zod_1.z.literal(constants_1.APP_DISTRIBUTION_TYPES.MARKETPLACE),
|
|
@@ -65,19 +66,13 @@ class CreateProjectTool extends types_1.Tool {
|
|
|
65
66
|
command = (0, command_1.addFlag)(command, 'distribution', distribution);
|
|
66
67
|
}
|
|
67
68
|
else if (projectBase === v3_1.PROJECT_WITH_APP) {
|
|
68
|
-
content.push({
|
|
69
|
-
type: 'text',
|
|
70
|
-
text: `Ask the user how they would you like to distribute the application? Options are ${constants_1.APP_DISTRIBUTION_TYPES.MARKETPLACE} and ${constants_1.APP_DISTRIBUTION_TYPES.PRIVATE}`,
|
|
71
|
-
});
|
|
69
|
+
content.push((0, content_1.formatTextContent)(`Ask the user how they would you like to distribute the application? Options are ${constants_1.APP_DISTRIBUTION_TYPES.MARKETPLACE} and ${constants_1.APP_DISTRIBUTION_TYPES.PRIVATE}`));
|
|
72
70
|
}
|
|
73
71
|
if (auth) {
|
|
74
72
|
command = (0, command_1.addFlag)(command, 'auth', auth);
|
|
75
73
|
}
|
|
76
74
|
else if (projectBase === v3_1.PROJECT_WITH_APP) {
|
|
77
|
-
content.push({
|
|
78
|
-
type: 'text',
|
|
79
|
-
text: `Ask the user which auth type they would like to use? Options are ${constants_1.APP_AUTH_TYPES.STATIC} and ${constants_1.APP_AUTH_TYPES.OAUTH}`,
|
|
80
|
-
});
|
|
75
|
+
content.push((0, content_1.formatTextContent)(`Ask the user which auth type they would like to use? Options are ${constants_1.APP_AUTH_TYPES.STATIC} and ${constants_1.APP_AUTH_TYPES.OAUTH}`));
|
|
81
76
|
}
|
|
82
77
|
if (content.length > 0) {
|
|
83
78
|
return {
|
|
@@ -88,28 +83,10 @@ class CreateProjectTool extends types_1.Tool {
|
|
|
88
83
|
command = (0, command_1.addFlag)(command, 'features', features || []);
|
|
89
84
|
try {
|
|
90
85
|
const { stdout, stderr } = await (0, project_1.runCommandInDir)(absoluteCurrentWorkingDirectory, command);
|
|
91
|
-
return
|
|
92
|
-
content: [
|
|
93
|
-
{
|
|
94
|
-
type: 'text',
|
|
95
|
-
text: stdout,
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
type: 'text',
|
|
99
|
-
text: stderr,
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
};
|
|
86
|
+
return (0, content_1.formatTextContents)(stdout, stderr);
|
|
103
87
|
}
|
|
104
88
|
catch (error) {
|
|
105
|
-
return {
|
|
106
|
-
content: [
|
|
107
|
-
{
|
|
108
|
-
type: 'text',
|
|
109
|
-
text: error instanceof Error ? error.message : `${error}`,
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
};
|
|
89
|
+
return (0, content_1.formatTextContents)(error instanceof Error ? error.message : `${error}`);
|
|
113
90
|
}
|
|
114
91
|
}
|
|
115
92
|
register() {
|
|
@@ -6,6 +6,7 @@ const zod_1 = require("zod");
|
|
|
6
6
|
const command_1 = require("../../utils/command");
|
|
7
7
|
const constants_1 = require("./constants");
|
|
8
8
|
const project_1 = require("../../utils/project");
|
|
9
|
+
const content_1 = require("../../utils/content");
|
|
9
10
|
const inputSchema = {
|
|
10
11
|
absoluteProjectPath: constants_1.absoluteProjectPath,
|
|
11
12
|
buildNumber: zod_1.z
|
|
@@ -25,10 +26,7 @@ class DeployProject extends types_1.Tool {
|
|
|
25
26
|
const content = [];
|
|
26
27
|
if (!buildNumber) {
|
|
27
28
|
const { stdout } = await (0, project_1.runCommandInDir)(absoluteProjectPath, `hs project list-builds --limit 100`);
|
|
28
|
-
content.push({
|
|
29
|
-
type: 'text',
|
|
30
|
-
text: `Ask the user which build number they would like to deploy? Build information: ${stdout}`,
|
|
31
|
-
});
|
|
29
|
+
content.push((0, content_1.formatTextContent)(`Ask the user which build number they would like to deploy? Build information: ${stdout}`));
|
|
32
30
|
}
|
|
33
31
|
else {
|
|
34
32
|
command = (0, command_1.addFlag)(command, 'build', buildNumber);
|
|
@@ -39,12 +37,7 @@ class DeployProject extends types_1.Tool {
|
|
|
39
37
|
};
|
|
40
38
|
}
|
|
41
39
|
const { stdout, stderr } = await (0, project_1.runCommandInDir)(absoluteProjectPath, command);
|
|
42
|
-
return
|
|
43
|
-
content: [
|
|
44
|
-
{ type: 'text', text: stdout },
|
|
45
|
-
{ type: 'text', text: stderr },
|
|
46
|
-
],
|
|
47
|
-
};
|
|
40
|
+
return (0, content_1.formatTextContents)(stdout, stderr);
|
|
48
41
|
}
|
|
49
42
|
register() {
|
|
50
43
|
return this.mcpServer.registerTool('deploy-hubspot-project', {
|
|
@@ -4,6 +4,7 @@ exports.GuidedWalkthroughTool = void 0;
|
|
|
4
4
|
const types_1 = require("../../types");
|
|
5
5
|
const zod_1 = require("zod");
|
|
6
6
|
const command_1 = require("../../utils/command");
|
|
7
|
+
const content_1 = require("../../utils/content");
|
|
7
8
|
const nextCommands = {
|
|
8
9
|
'hs init': 'hs auth',
|
|
9
10
|
'hs auth': 'hs project create',
|
|
@@ -32,23 +33,9 @@ class GuidedWalkthroughTool extends types_1.Tool {
|
|
|
32
33
|
async handler({ command }) {
|
|
33
34
|
if (command) {
|
|
34
35
|
const { stdout } = await (0, command_1.execAsync)(`${command} --help`);
|
|
35
|
-
return {
|
|
36
|
-
content: [
|
|
37
|
-
{
|
|
38
|
-
type: 'text',
|
|
39
|
-
text: `Display this help output for the user amd wait for them to acknowledge: ${stdout}. ${nextCommands[command] ? `Once they are ready, A good command to look at next is ${nextCommands[command]}` : ''}`,
|
|
40
|
-
},
|
|
41
|
-
],
|
|
42
|
-
};
|
|
36
|
+
return (0, content_1.formatTextContents)(`Display this help output for the user amd wait for them to acknowledge: ${stdout}. ${nextCommands[command] ? `Once they are ready, A good command to look at next is ${nextCommands[command]}` : ''}`);
|
|
43
37
|
}
|
|
44
|
-
return
|
|
45
|
-
content: [
|
|
46
|
-
{
|
|
47
|
-
type: 'text',
|
|
48
|
-
text: 'Is there another command you would like to learn more about?',
|
|
49
|
-
},
|
|
50
|
-
],
|
|
51
|
-
};
|
|
38
|
+
return (0, content_1.formatTextContents)('Is there another command you would like to learn more about?');
|
|
52
39
|
}
|
|
53
40
|
register() {
|
|
54
41
|
return this.mcpServer.registerTool('guided-walkthrough-hubspot-cli', {
|
|
@@ -8,6 +8,7 @@ const types_1 = require("../../types");
|
|
|
8
8
|
const project_1 = require("../../utils/project");
|
|
9
9
|
const constants_1 = require("./constants");
|
|
10
10
|
const zod_1 = __importDefault(require("zod"));
|
|
11
|
+
const content_1 = require("../../utils/content");
|
|
11
12
|
const inputSchema = {
|
|
12
13
|
absoluteProjectPath: constants_1.absoluteProjectPath,
|
|
13
14
|
};
|
|
@@ -21,12 +22,7 @@ class UploadProjectTools extends types_1.Tool {
|
|
|
21
22
|
}
|
|
22
23
|
async handler({ absoluteProjectPath, }) {
|
|
23
24
|
const { stdout, stderr } = await (0, project_1.runCommandInDir)(absoluteProjectPath, `hs project upload --force-create`);
|
|
24
|
-
return
|
|
25
|
-
content: [
|
|
26
|
-
{ type: 'text', text: stdout },
|
|
27
|
-
{ type: 'text', text: stderr },
|
|
28
|
-
],
|
|
29
|
-
};
|
|
25
|
+
return (0, content_1.formatTextContents)(stdout, stderr);
|
|
30
26
|
}
|
|
31
27
|
register() {
|
|
32
28
|
return this.mcpServer.registerTool('upload-hubspot-project', {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatTextContents = formatTextContents;
|
|
4
|
+
exports.formatTextContent = formatTextContent;
|
|
5
|
+
function formatTextContents(...outputs) {
|
|
6
|
+
const content = [];
|
|
7
|
+
outputs.forEach(output => {
|
|
8
|
+
if (output !== undefined) {
|
|
9
|
+
content.push(formatTextContent(output));
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return {
|
|
13
|
+
content,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function formatTextContent(text) {
|
|
17
|
+
return {
|
|
18
|
+
type: 'text',
|
|
19
|
+
text,
|
|
20
|
+
};
|
|
21
|
+
}
|
package/package.json
CHANGED