Skip to main content
Glama

project_close

Close a project TCP server and optionally save its state before termination to manage resources and preserve work.

Instructions

Close a project TCP server with optional save

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectIdYesProject ID to close
saveNoSave project before closing (default: false)

Implementation Reference

  • Core handler method that closes the Visum project TCP server: checks existence, optionally saves, sends shutdown command via TCP, removes from active servers registry.
    async closeProject(projectId: string, save: boolean = false): Promise<any> {
      const serverInfo = this.activeServers.get(projectId);
      if (!serverInfo) {
        return {
          success: false,
          message: 'Progetto non trovato'
        };
      }
    
      console.error(`CLOSING: Chiusura progetto: ${serverInfo.projectName}`);
    
      try {
        // Salva se richiesto
        if (save) {
          console.error('SAVING: Salvataggio progetto...');
          await this.saveProject(projectId);
        }
    
        // Invia comando di shutdown al server
        await this.sendCommandToServer(projectId, { type: 'shutdown' });
    
        // Rimuovi dal registry
        this.activeServers.delete(projectId);
        this.saveRegistry();
    
        return {
          success: true,
          message: `Progetto ${serverInfo.projectName} chiuso${save ? ' e salvato' : ''}`
        };
      } catch (error) {
        return {
          success: false,
          message: `Errore chiusura progetto: ${(error as Error).message}`
        };
      }
    }
  • MCP tool registration for 'project_close' including schema (projectId, optional save) and thin wrapper handler that calls ProjectServerManager.closeProject and formats MCP response.
    server.tool(
      "project_close",
      "Close a project TCP server with optional save",
      {
        projectId: z.string().describe("Project ID to close"),
        save: z.boolean().optional().describe("Save project before closing (default: false)")
      },
      async ({ projectId, save }) => {
        try {
          const result = await serverManager.closeProject(projectId, save || false);
          
          if (result.success) {
            return {
              content: [
                {
                  type: "text",
                  text: `šŸ”š **Progetto Chiuso**\n\nāœ… ${result.message}`
                }
              ]
            };
          } else {
            return {
              content: [
                {
                  type: "text",
                  text: `āŒ **Errore Chiusura**\n\n${result.message}`
                }
              ]
            };
          }
        } catch (error) {
          return {
            content: [
              {
                type: "text",
                text: `āŒ **Errore:** ${error instanceof Error ? error.message : String(error)}`
              }
            ]
          };
        }
      }
    );
  • Zod schema defining input parameters for the project_close tool.
      projectId: z.string().describe("Project ID to close"),
      save: z.boolean().optional().describe("Save project before closing (default: false)")
    },
  • Helper method used by closeProject to send the shutdown command over TCP to the project 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
      });
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but provides minimal behavioral insight. It mentions 'optional save' but doesn't disclose what 'close' entails (e.g., whether it terminates processes, frees resources, or requires specific permissions), nor does it cover error handling or side effects like data loss if save is false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core action ('Close a project TCP server') and adds a concise modifier ('with optional save'). There is no wasted verbiage, making it highly focused and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations and no output schema, the description is insufficient. It lacks details on what 'close' means operationally, the implications of the save option, potential errors, or return values, leaving significant gaps in understanding the tool's full behavior and outcomes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents both parameters. The description adds no additional meaning beyond implying 'save' relates to project preservation before closure, but this is already clear from the schema. Baseline 3 is appropriate as the schema handles parameter documentation adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Close') and resource ('a project TCP server'), making the purpose understandable. It distinguishes from siblings like 'project_open' and 'project_shutdown_instance' by focusing on server closure with optional save, though it doesn't explicitly contrast with all similar tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like 'project_shutdown_instance' or 'project_status'. The description mentions an optional save feature but doesn't explain when to enable it or what happens if omitted, leaving usage context unclear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/multiluca2020/visum-thinker-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server