Skip to main content
Glama
omgwtfwow

MCP Server for Crawl4AI

by omgwtfwow

manage_session

Manage browser sessions to maintain state across web crawling operations. Create persistent sessions, clear old ones, or list active sessions for handling forms, logins, and multi-step processes.

Instructions

[SESSION MANAGEMENT] Unified tool for managing browser sessions. Supports three actions:

• CREATE: Start a persistent browser session that maintains state across calls • CLEAR: Remove a session from local tracking • LIST: Show all active sessions with age and usage info

USAGE EXAMPLES:

  1. Create session: {action: "create", session_id: "my-session", initial_url: "https://example.com"}

  2. Clear session: {action: "clear", session_id: "my-session"}

  3. List sessions: {action: "list"}

Browser sessions maintain ALL state (cookies, localStorage, page) across multiple crawl calls. Essential for: forms, login flows, multi-step processes, maintaining state across operations.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform: create, clear, or list
session_idNoSession identifier. Required for action="clear". Optional for create (auto-generated if omitted).
initial_urlNoURL to load when creating session (action="create").
browser_typeNoBrowser engine for the session (action="create").chromium

Implementation Reference

  • Full implementation of SessionHandlers class. The manageSession method (lines 4-28) is the entry point for the 'manage_session' tool, dispatching based on action to private methods that handle session creation (including optional initial crawl), clearing, and listing active sessions with metadata.
    export class SessionHandlers extends BaseHandler {
      async manageSession(options: {
        action: 'create' | 'clear' | 'list';
        session_id?: string;
        initial_url?: string;
        browser_type?: string;
      }) {
        switch (options.action) {
          case 'create':
            return this.createSession({
              session_id: options.session_id,
              initial_url: options.initial_url,
              browser_type: options.browser_type,
            });
          case 'clear':
            if (!options.session_id) {
              throw new Error('session_id is required for clear action');
            }
            return this.clearSession({ session_id: options.session_id });
          case 'list':
            return this.listSessions();
          default:
            // This should never happen due to TypeScript types, but handle it for runtime safety
            throw new Error(`Invalid action: ${(options as { action: string }).action}`);
        }
      }
    
      private async createSession(options: { session_id?: string; initial_url?: string; browser_type?: string }) {
        try {
          // Generate session ID if not provided
          const sessionId = options.session_id || `session-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
    
          // Store session info locally
          this.sessions.set(sessionId, {
            id: sessionId,
            created_at: new Date(),
            last_used: new Date(),
            initial_url: options.initial_url,
            metadata: {
              browser_type: options.browser_type || 'chromium',
            },
          });
    
          // If initial_url provided, make first crawl to establish session
          if (options.initial_url) {
            try {
              await this.axiosClient.post(
                '/crawl',
                {
                  urls: [options.initial_url],
                  browser_config: {
                    headless: true,
                    browser_type: options.browser_type || 'chromium',
                  },
                  crawler_config: {
                    session_id: sessionId,
                    cache_mode: 'BYPASS',
                  },
                },
                {
                  timeout: 30000, // 30 second timeout for initial crawl
                },
              );
    
              // Update last_used
              const session = this.sessions.get(sessionId);
              if (session) {
                session.last_used = new Date();
              }
            } catch (error) {
              // Session created but initial crawl failed - still return success
              console.error(`Initial crawl failed for session ${sessionId}:`, error);
            }
          }
    
          return {
            content: [
              {
                type: 'text',
                text: `Session created successfully:\nSession ID: ${sessionId}\nBrowser: ${options.browser_type || 'chromium'}\n${options.initial_url ? `Pre-warmed with: ${options.initial_url}` : 'Ready for use'}\n\nUse this session_id with the crawl tool to maintain state across requests.`,
              },
            ],
            // Include all session parameters for easier programmatic access
            session_id: sessionId,
            browser_type: options.browser_type || 'chromium',
            initial_url: options.initial_url,
            created_at: this.sessions.get(sessionId)?.created_at.toISOString(),
          };
        } catch (error) {
          throw this.formatError(error, 'create session');
        }
      }
    
      private async clearSession(options: { session_id: string }) {
        try {
          // Remove from local store
          const deleted = this.sessions.delete(options.session_id);
    
          // Note: The actual browser session in Crawl4AI will be cleaned up
          // automatically after inactivity or when the server restarts
    
          return {
            content: [
              {
                type: 'text',
                text: deleted
                  ? `Session cleared successfully: ${options.session_id}`
                  : `Session not found: ${options.session_id}`,
              },
            ],
          };
        } catch (error) {
          throw this.formatError(error, 'clear session');
        }
      }
    
      private async listSessions() {
        try {
          // Return locally stored sessions
          const sessions = Array.from(this.sessions.entries()).map(([id, info]) => {
            const ageMinutes = Math.floor((Date.now() - info.created_at.getTime()) / 60000);
            const lastUsedMinutes = Math.floor((Date.now() - info.last_used.getTime()) / 60000);
    
            return {
              session_id: id,
              created_at: info.created_at.toISOString(),
              last_used: info.last_used.toISOString(),
              age_minutes: ageMinutes,
              last_used_minutes_ago: lastUsedMinutes,
              initial_url: info.initial_url,
              browser_type: info.metadata?.browser_type || 'chromium',
            };
          });
    
          if (sessions.length === 0) {
            return {
              content: [
                {
                  type: 'text',
                  text: 'No active sessions found.',
                },
              ],
            };
          }
    
          const sessionList = sessions
            .map(
              (session) =>
                `- ${session.session_id} (${session.browser_type}, created ${session.age_minutes}m ago, last used ${session.last_used_minutes_ago}m ago)`,
            )
            .join('\n');
    
          return {
            content: [
              {
                type: 'text',
                text: `Active sessions (${sessions.length}):\n${sessionList}`,
              },
            ],
          };
        } catch (error) {
          throw this.formatError(error, 'list sessions');
        }
      }
    }
  • Zod schema for input validation of manage_session tool. Uses discriminatedUnion on 'action' field to validate parameters for 'create', 'clear', or 'list' operations.
    export const ManageSessionSchema = z.discriminatedUnion('action', [
      z.object({
        action: z.literal('create'),
        session_id: z.string().optional(),
        initial_url: z.string().url().optional(),
        browser_type: z.enum(['chromium', 'firefox', 'webkit']).optional(),
      }),
      z.object({
        action: z.literal('clear'),
        session_id: z.string(),
      }),
      z.object({
        action: z.literal('list'),
      }),
    ]);
  • src/server.ts:750-789 (registration)
    Registration of 'manage_session' tool in the ListTools response, including name, detailed description, and inputSchema matching the Zod schema.
    {
      name: 'manage_session',
      description:
        '[SESSION MANAGEMENT] Unified tool for managing browser sessions. Supports three actions:\n\n' +
        '• CREATE: Start a persistent browser session that maintains state across calls\n' +
        '• CLEAR: Remove a session from local tracking\n' +
        '• LIST: Show all active sessions with age and usage info\n\n' +
        'USAGE EXAMPLES:\n' +
        '1. Create session: {action: "create", session_id: "my-session", initial_url: "https://example.com"}\n' +
        '2. Clear session: {action: "clear", session_id: "my-session"}\n' +
        '3. List sessions: {action: "list"}\n\n' +
        'Browser sessions maintain ALL state (cookies, localStorage, page) across multiple crawl calls. Essential for: forms, login flows, multi-step processes, maintaining state across operations.',
      inputSchema: {
        // Anthropic/Claude tools require top-level schemas to be a plain object without oneOf/allOf/anyOf
        type: 'object',
        properties: {
          action: {
            type: 'string',
            description: 'Action to perform: create, clear, or list',
            enum: ['create', 'clear', 'list'],
          },
          session_id: {
            type: 'string',
            description:
              'Session identifier. Required for action="clear". Optional for create (auto-generated if omitted).',
          },
          initial_url: {
            type: 'string',
            description: 'URL to load when creating session (action="create").',
          },
          browser_type: {
            type: 'string',
            enum: ['chromium', 'firefox', 'webkit'],
            description: 'Browser engine for the session (action="create").',
            default: 'chromium',
          },
        },
        required: ['action'],
      },
    },
  • src/server.ts:885-888 (registration)
    Dispatch handler in the CallToolRequest switch statement that validates arguments using ManageSessionSchema and executes this.sessionHandlers.manageSession.
    case 'manage_session':
      return await this.validateAndExecute('manage_session', args, ManageSessionSchema, async (validatedArgs) =>
        this.sessionHandlers.manageSession(validatedArgs),
      );
  • src/server.ts:84-84 (registration)
    Instantiation of SessionHandlers class instance (this.sessionHandlers) in the server constructor, passing service, axiosClient, and sessions Map.
    this.sessionHandlers = new SessionHandlers(this.service, this.axiosClient, this.sessions);

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/omgwtfwow/mcp-crawl4ai-ts'

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