project_save
Save the currently opened project in the Visum Thinker MCP Server to preserve work and prevent data loss. Optionally save with a different filename for version control.
Instructions
Save the currently opened project in its TCP server
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID to save | |
| saveAs | No | Optional: Save with a different filename |
Implementation Reference
- src/index-backup.ts:1062-1102 (registration)MCP tool registration for 'project_save', including inline Zod schema for parameters and the handler function that delegates to ProjectServerManager.saveProject."project_save", "Save the currently opened project in its TCP server", { projectId: z.string().describe("Project ID to save"), saveAs: z.string().optional().describe("Optional: Save with a different filename") }, async ({ projectId, saveAs }) => { try { const result = await serverManager.saveProject(projectId, saveAs); if (result.success) { return { content: [ { type: "text", text: `š¾ **Progetto Salvato**\n\nā ${result.message}${saveAs ? `\n\nš Salvato come: ${saveAs}` : ''}` } ] }; } else { return { content: [ { type: "text", text: `ā **Errore Salvataggio**\n\n${result.message || result.error}` } ] }; } } catch (error) { return { content: [ { type: "text", text: `ā **Errore:** ${error instanceof Error ? error.message : String(error)}` } ] }; } } );
- src/project-server-manager.ts:168-182 (handler)Handler logic in ProjectServerManager.saveProject that retrieves server info and sends a TCP command {type: 'save_project', saveAs} to the project-specific TCP server process for executing the save operation.async saveProject(projectId: string, saveAs: string | null = null): Promise<any> { const serverInfo = this.activeServers.get(projectId); if (!serverInfo) { return { success: false, message: 'Progetto non trovato' }; } // Invia comando di salvataggio al server TCP return await this.sendCommandToServer(projectId, { type: 'save_project', saveAs: saveAs }); }
- Helper method sendCommandToServer that establishes TCP connection to project server, sends the 'save_project' command as JSON, and parses the response from the server.async sendCommandToServer(projectId: string, command: any): Promise<any> { const serverInfo = this.activeServers.get(projectId); if (!serverInfo) { throw new Error('Server progetto non trovato'); } return new Promise((resolve, reject) => { const client = createConnection(serverInfo.port, 'localhost'); let buffer = ''; client.on('connect', () => { const message = JSON.stringify({ ...command, requestId: Date.now() }); client.write(message + '\n'); }); client.on('data', (data: any) => { buffer += data.toString(); // Dividi per newlines per separare i messaggi const messages = buffer.split('\n'); buffer = messages.pop() || ''; // Mantieni l'ultimo pezzo (potrebbe essere incompleto) for (const message of messages) { if (message.trim()) { try { // Rimuovi backslash-n letterali che il server TCP Python aggiunge const cleanedResponse = message.replace(/\\n$/g, ''); const response = JSON.parse(cleanedResponse); // Ignora il messaggio di welcome, aspetta la risposta vera if (response.type === 'project_welcome') { continue; } // Risposta al comando ricevuta (query_result, save_result, error, etc.) if (response.type === 'query_result' || response.type === 'save_result' || response.type === 'error' || response.type === 'shutdown_ack' || response.result !== undefined) { client.end(); resolve(response); return; } } catch (error) { // Ignora messaggi malformati, continua ad aspettare console.error('WARN: Messaggio TCP non parsabile:', message); } } } }); client.on('error', (error: any) => { reject(error); }); setTimeout(() => { client.end(); reject(new Error('Timeout comando server')); }, 300000); // 5 minuti timeout per operazioni pesanti su reti grandi }); }