Skip to main content
Glama
ttommyth

Interactive MCP

start_intensive_chat

Start a persistent chat session to collect multiple user inputs quickly for brainstorming, multi-step processes, or gathering sequential preferences.

Instructions

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sessionTitleYesTitle for the intensive chat session

Implementation Reference

  • Core handler function that implements the logic for starting an intensive chat session: creates temp dir, spawns platform-specific child process for UI, stores session in global map, returns session ID.
    export async function startIntensiveChatSession(
      title: string,
      timeoutSeconds?: number,
    ): Promise<string> {
      // Create a session directory
      const sessionDir = await createSessionDir();
    
      // Generate a unique session ID
      const sessionId = path.basename(sessionDir).replace('intensive-chat-', '');
    
      // Path to the UI script - Updated to use the compiled 'ui.js' filename
      const uiScriptPath = path.join(__dirname, 'ui.js');
    
      // Create options payload for the UI
      const options = {
        sessionId,
        title,
        outputDir: sessionDir,
        timeoutSeconds,
      };
    
      // Encode options as base64 payload
      const payload = Buffer.from(JSON.stringify(options)).toString('base64');
    
      // Platform-specific spawning
      const platform = os.platform();
      let childProcess: ChildProcess;
    
      if (platform === 'darwin') {
        // macOS
        // Escape potential special characters in paths/payload for the shell command
        // For the shell command executed by 'do script', we primarily need to handle spaces
        // or other characters that might break the command if paths aren't quoted.
        // The `${...}` interpolation within backticks handles basic variable insertion.
        // Quoting the paths within nodeCommand handles spaces.
        const escapedScriptPath = uiScriptPath; // Keep original path, rely on quotes below
        const escapedPayload = payload; // Keep original payload, rely on quotes below
    
        // Construct the command string directly for the shell. Quotes handle paths with spaces.
        const nodeBin = process.execPath;
        const nodeCommand = `exec "${nodeBin}" "${escapedScriptPath}" "${escapedPayload}"; exit 0`;
    
        // Escape the node command for osascript's AppleScript string:
        // 1. Escape existing backslashes (\ -> \\)
        // 2. Escape double quotes (" -> \")
        const escapedNodeCommand = nodeCommand
          // Escape backslashes first
          .replace(/\\/g, '\\\\') // Using /\\/g instead of /\/g
          // Then escape double quotes
          .replace(/"/g, '\\"');
    
        // Activate Terminal first, then do script with exec
        const command = `osascript -e 'tell application "Terminal" to activate' -e 'tell application "Terminal" to do script "${escapedNodeCommand}"'`;
        const commandArgs: string[] = []; // No args needed when command is a single string for shell
    
        // Fallback launcher using .command + open -a Terminal
        const launchViaOpenCommand = async () => {
          try {
            const launcherPath = path.join(
              sessionDir,
              `interactive-mcp-intchat-${sessionId}.command`,
            );
            const scriptContent = `#!/bin/bash\nexec "${process.execPath}" "${escapedScriptPath}" "${escapedPayload}"\n`;
            await fs.writeFile(launcherPath, scriptContent, 'utf8');
            await fs.chmod(launcherPath, 0o755);
            const openProc = spawn('open', ['-a', 'Terminal', launcherPath], {
              stdio: ['ignore', 'ignore', 'ignore'],
              detached: true,
            });
            openProc.unref();
          } catch (e) {
            logger.error(
              { error: e },
              'Fallback open -a Terminal failed (intensive chat)',
            );
          }
        };
    
        childProcess = spawn(command, commandArgs, {
          stdio: ['ignore', 'ignore', 'ignore'],
          shell: true,
          detached: true,
        });
    
        childProcess.on('error', () => {
          void launchViaOpenCommand();
        });
        childProcess.on('close', (code: number | null) => {
          if (code !== null && code !== 0) {
            void launchViaOpenCommand();
          }
        });
      } else if (platform === 'win32') {
        // Windows
        childProcess = spawn(process.execPath, [uiScriptPath, payload], {
          stdio: ['ignore', 'ignore', 'ignore'],
          shell: true,
          detached: true,
          windowsHide: false,
        });
      } else {
        // Linux or other - use original method (might not pop up window)
        childProcess = spawn(process.execPath, [uiScriptPath, payload], {
          stdio: ['ignore', 'ignore', 'ignore'],
          shell: true,
          detached: true,
        });
      }
    
      // Unref the process so it can run independently
      childProcess.unref();
    
      // Store session info
      activeSessions[sessionId] = {
        id: sessionId,
        process: childProcess, // Use the conditionally spawned process
        outputDir: sessionDir,
        lastHeartbeatTime: Date.now(),
        isActive: true,
        title,
        timeoutSeconds,
      };
    
      // Wait a bit to ensure the UI has started
      await new Promise((resolve) => setTimeout(resolve, 500));
    
      return sessionId;
    }
  • src/index.ts:180-228 (registration)
    MCP server registration of the 'start_intensive_chat' tool, which validates input via schema, calls the handler startIntensiveChatSession, tracks session, and returns success/error response.
    if (isToolEnabled('start_intensive_chat')) {
      // Use properties from the imported intensiveChatTools object
      server.tool(
        'start_intensive_chat',
        // Description is a function here
        typeof intensiveChatTools.start.description === 'function'
          ? intensiveChatTools.start.description(globalTimeoutSeconds)
          : intensiveChatTools.start.description,
        intensiveChatTools.start.schema, // Use schema property
        async (args) => {
          // Use inferred args type
          const { sessionTitle } = args;
          try {
            // Start a new intensive chat session, passing global timeout
            const sessionId = await startIntensiveChatSession(
              sessionTitle,
              globalTimeoutSeconds,
            );
    
            // Track this session for the client
            activeChatSessions.set(sessionId, sessionTitle);
    
            return {
              content: [
                {
                  type: 'text',
                  text: `Intensive chat session started successfully. Session ID: ${sessionId}`,
                },
              ],
            };
          } catch (error: unknown) {
            let errorMessage = 'Failed to start intensive chat session.';
            if (error instanceof Error) {
              errorMessage = `Failed to start intensive chat session: ${error.message}`;
            } else if (typeof error === 'string') {
              errorMessage = `Failed to start intensive chat session: ${error}`;
            }
            return {
              content: [
                {
                  type: 'text',
                  text: errorMessage,
                },
              ],
            };
          }
        },
      );
    }
  • Tool definition including schema (sessionTitle: string), capability/parameters, and detailed description for start_intensive_chat.
    const startToolDefinition: ToolDefinition = {
      capability: startCapability,
      description: startDescription,
      schema: startSchema,
    };
  • Capability definition with input parameters schema for the tool.
    const startCapability: ToolCapabilityInfo = {
      description:
        'Start an intensive chat session for gathering multiple answers quickly.',
      parameters: {
        type: 'object',
        properties: {
          sessionTitle: {
            type: 'string',
            description: 'Title for the intensive chat session',
          },
        },
        required: ['sessionTitle'],
      },
    };
  • src/index.ts:28-31 (registration)
    Initial declaration of tool capabilities including start_intensive_chat before filtering.
    const allToolCapabilities = {
      request_user_input: requestUserInputTool.capability,
      message_complete_notification: messageCompleteNotificationTool.capability,
      start_intensive_chat: intensiveChatTools.start.capability,
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key traits: it opens a persistent console window, returns a session ID for subsequent use, requires closure with 'stop_intensive_chat,' and emphasizes immediate follow-up questions. However, it lacks details on error handling or performance limits, preventing a perfect score.

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

Conciseness3/5

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

The description is structured with sections like '<importantNotes>' and '<bestPractices>,' which aids readability, but it is overly verbose and repetitive. For example, the purpose is stated multiple times, and some points are reiterated across sections, reducing efficiency. It could be more front-loaded and condensed.

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

Completeness4/5

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

Given the tool's complexity (initiating a multi-step chat session) and lack of annotations or output schema, the description is largely complete. It covers usage, behavioral expectations, parameters, and integration with sibling tools. However, it omits details on error cases or session limits, leaving minor gaps.

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?

The schema description coverage is 100%, so the schema already documents the single parameter 'sessionTitle.' The description adds minimal value beyond this, only repeating the parameter in the '<parameters>' section without additional context like examples of effective titles. Thus, it meets the baseline of 3.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Start an intensive chat session for gathering multiple answers quickly from the user.' It specifies the verb ('Start'), resource ('intensive chat session'), and distinguishes it from siblings like 'ask_intensive_chat' and 'stop_intensive_chat' by indicating it initiates the session.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool vs. alternatives. The '<whenToUseThisTool>' section lists specific scenarios (e.g., 'more than 2-3 questions,' 'multi-step process'), and the '<bestPractices>' section advises against using it when other tools can answer questions, naming alternatives like 'Cursor tools or other MCP Server tools.'

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/ttommyth/interactive-mcp'

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