Skip to main content
Glama
mikeysrecipes

interactive-mcp

start_intensive_chat

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

Instructions

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sessionTitleYesTitle for the intensive chat session

Implementation Reference

  • Core handler function `startIntensiveChatSession` that implements the logic for starting an intensive chat session: creates temp dir, spawns platform-specific child process running ui.js with session payload.
    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 nodeCommand = `exec node "${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
    
        childProcess = spawn(command, commandArgs, {
          stdio: ['ignore', 'ignore', 'ignore'],
          shell: true,
          detached: true,
        });
      } else if (platform === 'win32') {
        // Windows
        childProcess = spawn('node', [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('node', [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,
      };
    
      // Wait a bit to ensure the UI has started
      await new Promise((resolve) => setTimeout(resolve, 500));
    
      return sessionId;
    }
  • src/index.ts:175-221 (registration)
    Registers the 'start_intensive_chat' MCP tool on the server, providing description, schema from tool-definitions, and inline async handler that calls startIntensiveChatSession and handles response/error formatting.
      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,
                },
              ],
            };
          }
        },
      );
    }
  • Defines the input schema (JSON Schema in capability.parameters and Zod schema) and tool definition object for 'start_intensive_chat' used in registration.
    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'],
      },
    };
    
    const startDescription: ToolRegistrationDescription = (
      globalTimeoutSeconds: number,
    ) => `<description>
    Start an intensive chat session for gathering multiple answers quickly from the user.
    **Highly recommended** for scenarios requiring a sequence of related inputs or confirmations.
    Very useful for gathering multiple answers from the user in a short period of time.
    Especially useful for brainstorming ideas or discussing complex topics with the user.
    </description>
    
    <importantNotes>
    - (!important!) Opens a persistent console window that stays open for multiple questions.
    - (!important!) Returns a session ID that **must** be used for subsequent questions via 'ask_intensive_chat'.
    - (!important!) **Must** be closed with 'stop_intensive_chat' when finished gathering all inputs.
    - (!important!) After starting a session, **immediately** continue asking all necessary questions using 'ask_intensive_chat' within the **same response message**. Do not end the response until the chat is closed with 'stop_intensive_chat'. This creates a seamless conversational flow for the user.
    </importantNotes>
    
    <whenToUseThisTool>
    - When you need to collect a series of quick answers from the user (more than 2-3 questions)
    - When setting up a project with multiple configuration options
    - When guiding a user through a multi-step process requiring input at each stage
    - When gathering sequential user preferences
    - When you want to maintain context between multiple related questions efficiently
    - When brainstorming ideas with the user interactively
    </whenToUseThisTool>
    
    <features>
    - Opens a persistent console window for continuous interaction
    - Supports starting with an initial question
    - Configurable timeout for each question (set via -t/--timeout, defaults to ${globalTimeoutSeconds} seconds)
    - Returns a session ID for subsequent interactions
    - Keeps full chat history visible to the user
    - Maintains state between questions
    </features>
    
    <bestPractices>
    - Use a descriptive session title related to the task
    - Start with a clear initial question when possible
    - Do not ask the question if you have another tool that can answer the question
      - e.g. when you searching file in the current repository, do not ask the question "Do you want to search for a file in the current repository?"
      - e.g. prefer to use other tools to find the answer (Cursor tools or other MCP Server tools)
    - Always store the returned session ID for later use
    - Always close the session when you're done with stop_intensive_chat
    </bestPractices>
    
    <parameters>
    - sessionTitle: Title for the intensive chat session (appears at the top of the console)
    </parameters>
    
    <examples>
    - Start session for project setup: { "sessionTitle": "Project Configuration" }
    </examples>`;
    
    const startSchema: ZodRawShape = {
      sessionTitle: z.string().describe('Title for the intensive chat session'),
    };
    
    const startToolDefinition: ToolDefinition = {
      capability: startCapability,
      description: startDescription,
      schema: startSchema,
    };

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

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