4545 */
4646
4747import type { ComposeDefinition } from "@mcpc/core" ;
48- import { access , mkdir , readFile , writeFile } from "node:fs/promises" ;
48+ import { mkdir , readFile , writeFile } from "node:fs/promises" ;
4949import { homedir } from "node:os" ;
5050import { dirname , join , resolve } from "node:path" ;
5151import process from "node:process" ;
@@ -116,57 +116,63 @@ function getUserConfigPath(): string {
116116
117117/**
118118 * Save configuration to user's config file (~/.mcpc/config.json)
119+ * Merges new agent if name differs, warns if name conflicts
119120 */
120- async function saveUserConfig ( config : MCPCConfig ) : Promise < void > {
121+ async function saveUserConfig (
122+ config : MCPCConfig ,
123+ newAgentName : string ,
124+ ) : Promise < void > {
121125 const configPath = getUserConfigPath ( ) ;
122126 const configDir = dirname ( configPath ) ;
123127
124128 try {
125- // Check if config file already exists
126- let exists = false ;
129+ // Try to load existing config
130+ let existingConfig : MCPCConfig | null = null ;
127131 try {
128- await access ( configPath ) ;
129- exists = true ;
132+ const content = await readFile ( configPath , "utf-8" ) ;
133+ existingConfig = JSON . parse ( content ) ;
130134 } catch {
131- // File doesn't exist, which is fine
135+ // File doesn't exist - will create new one
132136 }
133137
134- if ( exists ) {
135- console . error ( `
136- ⚠ Configuration file already exists: ${ configPath }
137-
138- To avoid overwriting your customized settings:
139- 1. Use a different output path with --config-file
140- 2. Or manually merge the new servers into your existing config
141- 3. Or delete the file first: rm ${ configPath }
138+ // Handle existing config
139+ if ( existingConfig ) {
140+ const hasConflict = existingConfig . agents . some (
141+ ( agent ) => agent . name === newAgentName ,
142+ ) ;
143+
144+ if ( hasConflict ) {
145+ console . error (
146+ `\n⚠ Agent "${ newAgentName } " already exists in ${ configPath } \n` +
147+ ` Use --name to choose a different name, or delete the existing agent first.\n` ,
148+ ) ;
149+ return ;
150+ }
142151
143- Skipping save to preserve your existing configuration.
144- ` ) ;
152+ // Merge new agent
153+ existingConfig . agents . push ( ...config . agents ) ;
154+ await writeFile (
155+ configPath ,
156+ JSON . stringify ( existingConfig , null , 2 ) ,
157+ "utf-8" ,
158+ ) ;
159+ console . error (
160+ `\n✓ Added agent "${ newAgentName } " (total: ${ existingConfig . agents . length } )\n` +
161+ ` Config: ${ configPath } \n` +
162+ ` Run: mcpc\n` ,
163+ ) ;
145164 return ;
146165 }
147166
148- // Create directory if it doesn't exist
167+ // Create new config
149168 await mkdir ( configDir , { recursive : true } ) ;
150-
151- // Write config file with pretty formatting
152169 await writeFile ( configPath , JSON . stringify ( config , null , 2 ) , "utf-8" ) ;
153-
154- console . error ( `
155- ✓ Configuration saved to: ${ configPath }
156-
157- Next steps:
158- 1. (Optional) Edit the config to add headers, env vars, etc.
159- Examples:
160- - Add headers: "headers": {"Authorization": "Bearer \${YOUR_TOKEN}"}
161- - Add env vars: "env": {"API_KEY": "\${API_KEY}"}
162-
163- 2. Run the server:
164- mcpc
165-
166- The config will be loaded automatically from ${ configPath }
167- ` ) ;
170+ console . error (
171+ `\n✓ Configuration saved to: ${ configPath } \n` +
172+ ` Run: mcpc\n` ,
173+ ) ;
168174 } catch ( error ) {
169- console . error ( `Warning: Failed to save config to ${ configPath } :` , error ) ;
175+ console . error ( `Failed to save config to ${ configPath } :` , error ) ;
170176 }
171177}
172178
@@ -181,12 +187,10 @@ async function createWrapConfig(args: {
181187 saveConfig ?: boolean ;
182188} ) : Promise < MCPCConfig > {
183189 if ( ! args . mcpServers || args . mcpServers . length === 0 ) {
184- console . error ( "Error: --wrap/--add requires at least one MCP server" ) ;
185190 console . error (
186- "Example: mcpc --wrap --mcp-stdio 'npx -y @wonderwhy-er/desktop-commander'" ,
187- ) ;
188- console . error (
189- "Multiple: mcpc --add --mcp-stdio 'npx -y server1' --mcp-http 'https://api.example.com'" ,
191+ "Error: --wrap/--add requires at least one MCP server\n" +
192+ "Example: mcpc --wrap --mcp-stdio 'npx -y @wonderwhy-er/desktop-commander'\n" +
193+ "Multiple: mcpc --add --mcp-stdio 'npx -y server1' --mcp-http 'https://api.example.com'" ,
190194 ) ;
191195 process . exit ( 1 ) ;
192196 }
@@ -208,9 +212,11 @@ async function createWrapConfig(args: {
208212 serverNames . push ( serverName ) ;
209213 refs . push ( `<tool name="${ serverName } .__ALL__"/>` ) ;
210214
211- console . error ( `Added MCP server: ${ serverName }
212- Transport: ${ spec . transportType }
213- Command: ${ spec . command } ${ spec . args . join ( " " ) } ` ) ;
215+ console . error (
216+ `Added MCP server: ${ serverName } \n` +
217+ ` Transport: ${ spec . transportType } \n` +
218+ ` Command: ${ spec . command } ${ spec . args . join ( " " ) } ` ,
219+ ) ;
214220 }
215221
216222 // Use custom name if provided, otherwise use merged server names
@@ -242,12 +248,13 @@ async function createWrapConfig(args: {
242248 } ;
243249
244250 const modeInfo = args . mode ? `\nMode: ${ args . mode } ` : "" ;
245- console . error ( `
246- Created wrap configuration for ${ serverNames . length } MCP server(s)${ modeInfo } ` ) ;
251+ console . error (
252+ `\nCreated configuration for ${ serverNames . length } MCP server(s)${ modeInfo } ` ,
253+ ) ;
247254
248255 // Save configuration to user's config file if requested
249256 if ( args . saveConfig ) {
250- await saveUserConfig ( config ) ;
257+ await saveUserConfig ( config , agentName ) ;
251258 }
252259
253260 return config ;
0 commit comments