@myvtp/mcp 0.1.0 → 0.3.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.
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Constants and client definitions for the install command
3
+ */
4
+ import { homedir } from 'os';
5
+ import { join } from 'path';
6
+ /**
7
+ * Supported MCP clients with their config locations
8
+ */
9
+ export const CLIENTS = [
10
+ {
11
+ id: 'claude-desktop',
12
+ name: 'Claude Desktop',
13
+ description: 'Anthropic\'s desktop app for Claude',
14
+ paths: {
15
+ darwin: join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
16
+ win32: join(process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json'),
17
+ linux: join(homedir(), '.config', 'Claude', 'claude_desktop_config.json'),
18
+ },
19
+ restartInstructions: 'Quit and restart Claude Desktop',
20
+ },
21
+ {
22
+ id: 'claude-code',
23
+ name: 'Claude Code',
24
+ description: 'Anthropic\'s CLI tool for Claude',
25
+ paths: {
26
+ darwin: join(homedir(), '.claude.json'),
27
+ win32: join(homedir(), '.claude.json'),
28
+ linux: join(homedir(), '.claude.json'),
29
+ },
30
+ restartInstructions: 'Start a new Claude Code session',
31
+ },
32
+ {
33
+ id: 'cursor',
34
+ name: 'Cursor',
35
+ description: 'AI-powered code editor',
36
+ paths: {
37
+ darwin: join(homedir(), '.cursor', 'mcp.json'),
38
+ win32: join(homedir(), '.cursor', 'mcp.json'),
39
+ linux: join(homedir(), '.cursor', 'mcp.json'),
40
+ },
41
+ restartInstructions: 'Restart Cursor',
42
+ },
43
+ {
44
+ id: 'project',
45
+ name: 'Project (.mcp.json)',
46
+ description: 'Project-level config in current directory',
47
+ paths: {
48
+ darwin: join(process.cwd(), '.mcp.json'),
49
+ win32: join(process.cwd(), '.mcp.json'),
50
+ linux: join(process.cwd(), '.mcp.json'),
51
+ },
52
+ projectLevel: true,
53
+ restartInstructions: 'Restart your AI coding assistant',
54
+ },
55
+ {
56
+ id: 'vscode',
57
+ name: 'VS Code',
58
+ description: 'Project-level MCP config for VS Code',
59
+ paths: {
60
+ darwin: join(process.cwd(), '.vscode', 'mcp.json'),
61
+ win32: join(process.cwd(), '.vscode', 'mcp.json'),
62
+ linux: join(process.cwd(), '.vscode', 'mcp.json'),
63
+ },
64
+ projectLevel: true,
65
+ restartInstructions: 'Reload VS Code window (Cmd/Ctrl+Shift+P → "Reload Window")',
66
+ },
67
+ {
68
+ id: 'windsurf',
69
+ name: 'Windsurf',
70
+ description: 'Codeium\'s AI code editor',
71
+ paths: {
72
+ darwin: join(homedir(), '.codeium', 'windsurf', 'mcp_config.json'),
73
+ win32: join(homedir(), '.codeium', 'windsurf', 'mcp_config.json'),
74
+ linux: join(homedir(), '.codeium', 'windsurf', 'mcp_config.json'),
75
+ },
76
+ restartInstructions: 'Restart Windsurf',
77
+ },
78
+ ];
79
+ /**
80
+ * The VTP MCP server configuration to inject
81
+ */
82
+ export function getVtpServerConfig() {
83
+ const isWindows = process.platform === 'win32';
84
+ if (isWindows) {
85
+ return {
86
+ command: 'cmd',
87
+ args: ['/c', 'npx', '-y', '@myvtp/mcp'],
88
+ };
89
+ }
90
+ return {
91
+ command: 'npx',
92
+ args: ['-y', '@myvtp/mcp'],
93
+ };
94
+ }
95
+ export const VTP_SERVER_NAME = 'vtp';
96
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/install/constants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Install command - configures VTP MCP server for AI coding clients
3
+ */
4
+ /**
5
+ * Main install command
6
+ */
7
+ export default function install(args: string[]): Promise<void>;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/install/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmLH;;GAEG;AACH,wBAA8B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGnE"}
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Install command - configures VTP MCP server for AI coding clients
3
+ */
4
+ import { checkbox, confirm } from '@inquirer/prompts';
5
+ import pc from 'picocolors';
6
+ import { detectAllClients, filterClients, getClientById } from './clients.js';
7
+ import { mergeVtpConfig, readConfig, writeConfig } from './config.js';
8
+ import { getVtpServerConfig, VTP_SERVER_NAME } from './constants.js';
9
+ /**
10
+ * Wrap a cancellable prompt to also cancel on Escape key
11
+ */
12
+ function withEscapeCancel(prompt) {
13
+ return new Promise((resolve, reject) => {
14
+ // Set up escape key listener
15
+ const onData = (data) => {
16
+ // Escape key is 0x1b (27) as a single byte
17
+ if (data.length === 1 && data[0] === 0x1b) {
18
+ prompt.cancel();
19
+ }
20
+ };
21
+ process.stdin.on('data', onData);
22
+ prompt
23
+ .then(resolve)
24
+ .catch(reject)
25
+ .finally(() => {
26
+ process.stdin.off('data', onData);
27
+ });
28
+ });
29
+ }
30
+ /**
31
+ * Parse CLI arguments into install options
32
+ */
33
+ function parseArgs(args) {
34
+ const options = {};
35
+ for (let i = 0; i < args.length; i++) {
36
+ const arg = args[i];
37
+ if (arg === '--yes' || arg === '-y') {
38
+ options.yes = true;
39
+ }
40
+ else if (arg === '--force' || arg === '-f') {
41
+ options.force = true;
42
+ }
43
+ else if (!arg.startsWith('-')) {
44
+ // Client ID
45
+ if (!options.clients) {
46
+ options.clients = [];
47
+ }
48
+ options.clients.push(arg);
49
+ }
50
+ }
51
+ return options;
52
+ }
53
+ /**
54
+ * Format client choice for the checkbox prompt
55
+ */
56
+ function formatClientChoice(detected) {
57
+ const { client, configExists, vtpConfigured, configPath } = detected;
58
+ let status = '';
59
+ let checked = true;
60
+ if (vtpConfigured) {
61
+ status = pc.yellow(' (already configured)');
62
+ checked = false;
63
+ }
64
+ else if (configExists) {
65
+ status = pc.dim(' (will update config)');
66
+ }
67
+ else if (client.projectLevel) {
68
+ status = pc.dim(` (will create ${configPath})`);
69
+ checked = false; // Don't auto-select project-level configs
70
+ }
71
+ else {
72
+ status = pc.dim(' (will create config)');
73
+ }
74
+ return {
75
+ name: `${client.name}${status}`,
76
+ value: client.id,
77
+ checked,
78
+ };
79
+ }
80
+ /**
81
+ * Configure a single client
82
+ */
83
+ function configureClient(detected, force) {
84
+ const { client, configPath, vtpConfigured } = detected;
85
+ // Skip if already configured and not forcing
86
+ if (vtpConfigured && !force) {
87
+ return {
88
+ client,
89
+ success: true,
90
+ action: 'skipped',
91
+ message: 'VTP already configured',
92
+ };
93
+ }
94
+ try {
95
+ const existingConfig = readConfig(configPath);
96
+ const vtpConfig = getVtpServerConfig();
97
+ const { config, action } = mergeVtpConfig(existingConfig, VTP_SERVER_NAME, vtpConfig, force);
98
+ if (action === 'skipped') {
99
+ return {
100
+ client,
101
+ success: true,
102
+ action: 'skipped',
103
+ message: 'VTP already configured',
104
+ };
105
+ }
106
+ writeConfig(configPath, config);
107
+ return {
108
+ client,
109
+ success: true,
110
+ action,
111
+ message: action === 'created' ? 'Created new config with VTP server' : 'Added VTP server to existing config',
112
+ };
113
+ }
114
+ catch (error) {
115
+ const message = error instanceof Error ? error.message : String(error);
116
+ return {
117
+ client,
118
+ success: false,
119
+ action: 'error',
120
+ message,
121
+ };
122
+ }
123
+ }
124
+ /**
125
+ * Print the results summary
126
+ */
127
+ function printResults(results) {
128
+ console.log();
129
+ const successResults = results.filter(r => r.success && r.action !== 'skipped');
130
+ const skippedResults = results.filter(r => r.action === 'skipped');
131
+ const errorResults = results.filter(r => !r.success);
132
+ // Print successes
133
+ for (const result of successResults) {
134
+ console.log(` ${pc.green('✓')} ${result.client.name}: ${result.message}`);
135
+ }
136
+ // Print skipped
137
+ for (const result of skippedResults) {
138
+ console.log(` ${pc.yellow('○')} ${result.client.name}: ${result.message}`);
139
+ }
140
+ // Print errors
141
+ for (const result of errorResults) {
142
+ console.log(` ${pc.red('✗')} ${result.client.name}: ${result.message}`);
143
+ }
144
+ // Print next steps if we configured anything
145
+ if (successResults.length > 0) {
146
+ console.log();
147
+ console.log(pc.bold(' Next steps:'));
148
+ const restartInstructions = [...new Set(successResults.map(r => r.client.restartInstructions))];
149
+ restartInstructions.forEach((instruction, i) => {
150
+ console.log(` ${i + 1}. ${instruction}`);
151
+ });
152
+ console.log();
153
+ console.log(pc.dim(' Once restarted, ask Claude to "deploy my app" to get started.'));
154
+ }
155
+ console.log();
156
+ }
157
+ /**
158
+ * Main install command
159
+ */
160
+ export default async function install(args) {
161
+ const options = parseArgs(args);
162
+ // Header
163
+ console.log();
164
+ console.log(pc.bold(' VTP MCP Server Setup'));
165
+ console.log(pc.dim(' Configure AI coding assistants to use VTP for deployments'));
166
+ console.log();
167
+ // Detect available clients
168
+ let detected = detectAllClients();
169
+ if (detected.length === 0) {
170
+ console.log(pc.yellow(' No supported AI clients detected.'));
171
+ console.log();
172
+ console.log(' Supported clients: Claude Desktop, Claude Code, Cursor, VS Code, Windsurf');
173
+ console.log();
174
+ return;
175
+ }
176
+ // Filter by specified clients if provided
177
+ if (options.clients && options.clients.length > 0) {
178
+ // Validate client IDs
179
+ for (const id of options.clients) {
180
+ if (!getClientById(id)) {
181
+ console.log(pc.red(` Unknown client: ${id}`));
182
+ console.log();
183
+ console.log(' Available clients: ' + detected.map(d => d.client.id).join(', '));
184
+ console.log();
185
+ return;
186
+ }
187
+ }
188
+ detected = filterClients(detected, options.clients);
189
+ }
190
+ let selectedClients;
191
+ if (options.yes) {
192
+ // Non-interactive mode: select all (or filtered) clients
193
+ selectedClients = detected;
194
+ if (selectedClients.length === 0) {
195
+ console.log(pc.yellow(' No clients to configure.'));
196
+ console.log();
197
+ return;
198
+ }
199
+ }
200
+ else {
201
+ // Interactive mode: show checkbox prompt
202
+ const choices = detected.map(formatClientChoice);
203
+ try {
204
+ const checkboxPrompt = checkbox({
205
+ message: 'Select AI clients to configure:',
206
+ choices,
207
+ pageSize: 10,
208
+ required: true,
209
+ });
210
+ const selectedIds = await withEscapeCancel(checkboxPrompt);
211
+ if (selectedIds.length === 0) {
212
+ console.log(pc.yellow(' No clients selected.'));
213
+ console.log();
214
+ return;
215
+ }
216
+ selectedClients = filterClients(detected, selectedIds);
217
+ // Check for already-configured clients and confirm overwrite
218
+ const alreadyConfigured = selectedClients.filter(c => c.vtpConfigured);
219
+ if (alreadyConfigured.length > 0 && !options.force) {
220
+ const names = alreadyConfigured.map(c => c.client.name).join(', ');
221
+ const confirmPrompt = confirm({
222
+ message: `${names} already have VTP configured. Overwrite?`,
223
+ default: false,
224
+ });
225
+ const shouldOverwrite = await withEscapeCancel(confirmPrompt);
226
+ if (!shouldOverwrite) {
227
+ selectedClients = selectedClients.filter(c => !c.vtpConfigured);
228
+ }
229
+ else {
230
+ options.force = true;
231
+ }
232
+ }
233
+ }
234
+ catch {
235
+ // User cancelled (Ctrl+C or Escape)
236
+ console.log();
237
+ return;
238
+ }
239
+ }
240
+ // Configure selected clients
241
+ const results = [];
242
+ for (const detected of selectedClients) {
243
+ const result = configureClient(detected, options.force || false);
244
+ results.push(result);
245
+ }
246
+ // Print results
247
+ printResults(results);
248
+ }
249
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/install/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Type definitions for the install command
3
+ */
4
+ export interface ClientConfig {
5
+ /** Display name for the client */
6
+ name: string;
7
+ /** Unique identifier used in CLI args */
8
+ id: string;
9
+ /** Description shown in the installer */
10
+ description: string;
11
+ /** Config file paths per platform */
12
+ paths: {
13
+ darwin?: string;
14
+ win32?: string;
15
+ linux?: string;
16
+ };
17
+ /** Whether this is a project-level config (like VS Code) */
18
+ projectLevel?: boolean;
19
+ /** Restart instructions after configuration */
20
+ restartInstructions: string;
21
+ }
22
+ export interface DetectedClient {
23
+ /** Client definition */
24
+ client: ClientConfig;
25
+ /** Resolved config path for current platform */
26
+ configPath: string;
27
+ /** Whether the config file exists */
28
+ configExists: boolean;
29
+ /** Whether VTP is already configured */
30
+ vtpConfigured: boolean;
31
+ /** The existing config content (if readable) */
32
+ existingConfig?: McpConfig;
33
+ }
34
+ export interface McpServerConfig {
35
+ command: string;
36
+ args: string[];
37
+ env?: Record<string, string>;
38
+ }
39
+ export interface McpConfig {
40
+ mcpServers?: Record<string, McpServerConfig>;
41
+ [key: string]: unknown;
42
+ }
43
+ export interface InstallOptions {
44
+ /** Run without prompts, configure all detected clients */
45
+ yes?: boolean;
46
+ /** Force overwrite existing VTP config */
47
+ force?: boolean;
48
+ /** Specific clients to configure (by id) */
49
+ clients?: string[];
50
+ }
51
+ export interface InstallResult {
52
+ client: ClientConfig;
53
+ success: boolean;
54
+ action: 'created' | 'updated' | 'skipped' | 'error';
55
+ message: string;
56
+ }
57
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/install/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,KAAK,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,4DAA4D;IAC5D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+CAA+C;IAC/C,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,MAAM,EAAE,YAAY,CAAC;IACrB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,aAAa,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type definitions for the install command
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/install/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * VTP MCP Server - handles tool requests from AI assistants
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/dist/server.js ADDED
@@ -0,0 +1,210 @@
1
+ /**
2
+ * VTP MCP Server - handles tool requests from AI assistants
3
+ */
4
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
7
+ import { existsSync } from 'fs';
8
+ import * as client from './client.js';
9
+ import { DeploySchema, GuideTypeSchema, toolDefinitions } from './tools.js';
10
+ const server = new Server({
11
+ name: 'vtp',
12
+ version: '0.7.0',
13
+ }, {
14
+ capabilities: {
15
+ tools: {},
16
+ },
17
+ });
18
+ // List available tools
19
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
20
+ tools: toolDefinitions,
21
+ }));
22
+ // Handle tool calls - all delegate to HTTP API via client
23
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
24
+ const { name, arguments: args } = request.params;
25
+ try {
26
+ switch (name) {
27
+ case 'list_app_types': {
28
+ const types = await client.listAppTypes();
29
+ const typeList = types
30
+ .map(t => `- **${t.displayName}** (${t.type})\n ${t.description}`)
31
+ .join('\n');
32
+ return {
33
+ content: [{
34
+ type: 'text',
35
+ text: `Supported app types:\n\n${typeList}\n\n` +
36
+ `Use get_deployment_guide with a type to see detailed instructions.`,
37
+ }],
38
+ };
39
+ }
40
+ case 'get_deployment_guide': {
41
+ const { type: guideType } = GuideTypeSchema.parse(args);
42
+ try {
43
+ const guide = await client.getDeploymentGuide(guideType);
44
+ return {
45
+ content: [{
46
+ type: 'text',
47
+ text: guide.content,
48
+ }],
49
+ };
50
+ }
51
+ catch (error) {
52
+ if (error instanceof Error && error.message.includes('guide_not_found')) {
53
+ const types = await client.listAppTypes();
54
+ const available = types.map(t => t.type).join(', ');
55
+ return {
56
+ content: [{
57
+ type: 'text',
58
+ text: `Unknown app type: "${guideType}"\n\nAvailable types: ${available}`,
59
+ }],
60
+ isError: true,
61
+ };
62
+ }
63
+ throw error;
64
+ }
65
+ }
66
+ case 'deploy': {
67
+ const { config, force } = DeploySchema.parse(args);
68
+ const configPath = config || './vtp.yaml';
69
+ // Validate config exists
70
+ if (!existsSync(configPath)) {
71
+ return {
72
+ content: [{
73
+ type: 'text',
74
+ text: `Error: Config file not found: ${configPath}\n\n` +
75
+ `Create a vtp.yaml file with:\n` +
76
+ ` name: My App Name # Display name\n` +
77
+ ` id: my-app # Optional: URL slug\n` +
78
+ ` type: static # or "node"\n` +
79
+ ` path: ./dist # folder to deploy\n\n` +
80
+ `Use list_app_types and get_deployment_guide for help.`,
81
+ }],
82
+ isError: true,
83
+ };
84
+ }
85
+ // Deploy via HTTP API
86
+ const result = await client.deploy(configPath, force ?? false);
87
+ // Handle conflict
88
+ if (result.error === 'conflict') {
89
+ const existingApp = result.existingApp;
90
+ return {
91
+ content: [{
92
+ type: 'text',
93
+ text: `App '${existingApp?.id}' already exists at ${existingApp?.url || 'unknown URL'}\n` +
94
+ `Name: ${existingApp?.name || 'unknown'}\n` +
95
+ `Status: ${existingApp?.status || 'unknown'}\n\n` +
96
+ `Use force: true to replace it.`,
97
+ }],
98
+ };
99
+ }
100
+ // Handle other errors
101
+ if (result.error) {
102
+ return {
103
+ content: [{
104
+ type: 'text',
105
+ text: `Error: ${result.message || result.error}`,
106
+ }],
107
+ isError: true,
108
+ };
109
+ }
110
+ // Success
111
+ const app = result.app;
112
+ const prefix = result.replaced ? 'Replaced' : 'Deployed';
113
+ return {
114
+ content: [{
115
+ type: 'text',
116
+ text: `${prefix} ${app.name} (@${app.id})\n` +
117
+ ` URL: ${app.url}\n` +
118
+ ` Type: ${app.type}\n` +
119
+ ` Status: ${app.status}`,
120
+ }],
121
+ };
122
+ }
123
+ case 'list': {
124
+ const apps = await client.listApps();
125
+ if (apps.length === 0) {
126
+ return {
127
+ content: [{
128
+ type: 'text',
129
+ text: 'No apps deployed yet.',
130
+ }],
131
+ };
132
+ }
133
+ const appList = apps
134
+ .map(app => {
135
+ const desc = app.description ? `\n ${app.description}` : '';
136
+ return `- ${app.name} (@${app.id}) - ${app.type} - ${app.status}${desc}\n ${app.url}`;
137
+ })
138
+ .join('\n');
139
+ return {
140
+ content: [{
141
+ type: 'text',
142
+ text: `Deployed apps:\n${appList}`,
143
+ }],
144
+ };
145
+ }
146
+ case 'list_supported_connections': {
147
+ const services = await client.listConnectionServices();
148
+ const serviceList = services
149
+ .map(service => {
150
+ const requiredFields = service.fields
151
+ .filter(f => f.required)
152
+ .map(f => f.name)
153
+ .join(', ');
154
+ const optionalFields = service.fields
155
+ .filter(f => !f.required)
156
+ .map(f => f.name);
157
+ const optionalText = optionalFields.length > 0
158
+ ? `\n Optional: ${optionalFields.join(', ')}`
159
+ : '';
160
+ return `- **${service.name}** (${service.id})\n` +
161
+ ` ${service.description}\n` +
162
+ ` Env prefix: ${service.envPrefix}_\n` +
163
+ ` Required: ${requiredFields}${optionalText}\n` +
164
+ ` Docs: ${service.docsUrl}`;
165
+ })
166
+ .join('\n\n');
167
+ return {
168
+ content: [{
169
+ type: 'text',
170
+ text: `Available connection services:\n\n${serviceList}\n\n` +
171
+ `**Usage in vtp.yaml:**\n` +
172
+ `\`\`\`yaml\n` +
173
+ `connections:\n` +
174
+ ` - openai\n` +
175
+ ` - anthropic\n` +
176
+ `\`\`\`\n\n` +
177
+ `The user must configure API keys at their VTP dashboard before deploying.\n` +
178
+ `Environment variables are injected as: {PREFIX}_{FIELD} (e.g., OPENAI_API_KEY)`,
179
+ }],
180
+ };
181
+ }
182
+ default:
183
+ return {
184
+ content: [{
185
+ type: 'text',
186
+ text: `Unknown tool: ${name}`,
187
+ }],
188
+ isError: true,
189
+ };
190
+ }
191
+ }
192
+ catch (error) {
193
+ const message = error instanceof Error ? error.message : String(error);
194
+ return {
195
+ content: [{
196
+ type: 'text',
197
+ text: `Error: ${message}`,
198
+ }],
199
+ isError: true,
200
+ };
201
+ }
202
+ });
203
+ // Start the server
204
+ async function main() {
205
+ const transport = new StdioServerTransport();
206
+ await server.connect(transport);
207
+ console.error('VTP MCP server running on stdio');
208
+ }
209
+ main().catch(console.error);
210
+ //# sourceMappingURL=server.js.map