<tools>
  <tool name="list_requests">
    <description>List and filter proxy requests using HTTPQL with pagination.</description>
    <parameters>
      <parameter name="httpql_filter" type="string" required="false">
        <description>HTTPQL filter using Caido's syntax:

        Integer fields (port, code, roundtrip, id) - eq, gt, gte, lt, lte, ne:
        - resp.code.eq:200, resp.code.gte:400, req.port.eq:443

        Text/byte fields (ext, host, method, path, query, raw) - regex:
        - req.method.regex:"POST", req.path.regex:"/api/.*", req.host.regex:".*.com"

        Date fields (created_at) - gt, lt with ISO formats:
        - req.created_at.gt:"2024-01-01T00:00:00Z"

        Special: source:intercept, preset:"name"</description>
      </parameter>
      <parameter name="start_page" type="integer" required="false">
        <description>Starting page (1-based)</description>
      </parameter>
      <parameter name="end_page" type="integer" required="false">
        <description>Ending page (1-based, inclusive)</description>
      </parameter>
      <parameter name="page_size" type="integer" required="false">
        <description>Requests per page</description>
      </parameter>
      <parameter name="sort_by" type="string" required="false">
        <description>Sort field from: "timestamp", "host", "status_code", "response_time", "response_size"</description>
      </parameter>
      <parameter name="sort_order" type="string" required="false">
        <description>Sort direction ("asc" or "desc")</description>
      </parameter>
      <parameter name="scope_id" type="string" required="false">
        <description>Scope ID to filter requests (use scope_rules to manage scopes)</description>
      </parameter>
    </parameters>
    <returns type="Dict[str, Any]">
      <description>Response containing:
        - 'requests': Request objects for page range
        - 'total_count': Total matching requests
        - 'start_page', 'end_page', 'page_size': Query parameters
        - 'returned_count': Requests in response</description>
    </returns>
    <examples>
  # POST requests to API with 200 responses
  <function=list_requests>
  <parameter=httpql_filter>req.method.eq:"POST" AND req.path.cont:"/api/"</parameter>
  <parameter=sort_by>response_time</parameter>
  <parameter=scope_id>scope123</parameter>
  </function>

  # Requests within specific scope
  <function=list_requests>
  <parameter=scope_id>scope123</parameter>
  <parameter=sort_by>timestamp</parameter>
  </function>
    </examples>
  </tool>

  <tool name="view_request">
    <description>View request/response data with search and pagination.</description>
    <parameters>
      <parameter name="request_id" type="string" required="true">
        <description>Request ID</description>
      </parameter>
      <parameter name="part" type="string" required="false">
        <description>Which part to return ("request" or "response")</description>
      </parameter>
      <parameter name="search_pattern" type="string" required="false">
        <description>Regex pattern to search content. Common patterns:
        - API endpoints: r"/api/[a-zA-Z0-9._/-]+"
        - URLs: r"https?://[^\\s<>"\']+"
        - Parameters: r'[?&][a-zA-Z0-9_]+=([^&\\s<>"\']+)'
        - Reflections: input_value in content</description>
      </parameter>
      <parameter name="page" type="integer" required="false">
        <description>Page number for pagination</description>
      </parameter>
      <parameter name="page_size" type="integer" required="false">
        <description>Lines per page</description>
      </parameter>
    </parameters>
    <returns type="Dict[str, Any]">
      <description>With search_pattern (COMPACT):
        - 'matches': [{match, before, after, position}] - max 20
        - 'total_matches': Total found
        - 'truncated': If limited to 20

        Without search_pattern (PAGINATION):
        - 'content': Page content
        - 'page': Current page
        - 'showing_lines': Range display
        - 'has_more': More pages available</description>
    </returns>
    <examples>
  # Find API endpoints in response
  <function=view_request>
  <parameter=request_id>123</parameter>
  <parameter=part>response</parameter>
  <parameter=search_pattern>/api/[a-zA-Z0-9._/-]+</parameter>
  </function>
    </examples>
  </tool>

  <tool name="send_request">
    <description>Send a simple HTTP request through proxy.</description>
    <parameters>
      <parameter name="method" type="string" required="true">
        <description>HTTP method (GET, POST, etc.)</description>
      </parameter>
      <parameter name="url" type="string" required="true">
        <description>Target URL</description>
      </parameter>
      <parameter name="headers" type="dict" required="false">
        <description>Headers as {"key": "value"}</description>
      </parameter>
      <parameter name="body" type="string" required="false">
        <description>Request body</description>
      </parameter>
      <parameter name="timeout" type="integer" required="false">
        <description>Request timeout</description>
      </parameter>
    </parameters>
  </tool>

  <tool name="repeat_request">
    <description>Repeat an existing proxy request with modifications for pentesting.

    PROPER WORKFLOW:
    1. Use browser_action to browse the target application
    2. Use list_requests() to see captured proxy traffic
    3. Use repeat_request() to modify and test specific requests

    This mirrors real pentesting: browse → capture → modify → test</description>
    <parameters>
      <parameter name="request_id" type="string" required="true">
        <description>ID of the original request to repeat (from list_requests)</description>
      </parameter>
      <parameter name="modifications" type="dict" required="false">
        <description>Changes to apply to the original request:
        - "url": New URL or modify existing one
        - "params": Dict to update query parameters
        - "headers": Dict to add/update headers
        - "body": New request body (replaces original)
        - "cookies": Dict to add/update cookies</description>
      </parameter>
    </parameters>
    <returns type="Dict[str, Any]">
      <description>Response data with status, headers, body, timing, and request details</description>
    </returns>
    <examples>
  # Modify POST body payload
  <function=repeat_request>
  <parameter=request_id>req_789</parameter>
  <parameter=modifications>{"body": "{\"username\":\"admin\",\"password\":\"admin\"}"}</parameter>
  </function>
    </examples>
  </tool>

  <tool name="scope_rules">
    <description>Manage proxy scope patterns for domain/file filtering using Caido's scope system.</description>
    <parameters>
      <parameter name="action" type="string" required="true">
        <description>Scope action:
        - get: Get specific scope by ID or list all if no ID
        - update: Update existing scope (requires scope_id and scope_name)
        - list: List all available scopes
        - create: Create new scope (requires scope_name)
        - delete: Delete scope (requires scope_id)</description>
      </parameter>
      <parameter name="allowlist" type="list" required="false">
        <description>Domain patterns to include. Examples: ["*.example.com", "api.test.com"]</description>
      </parameter>
      <parameter name="denylist" type="list" required="false">
        <description>Patterns to exclude. Some common extensions:
        ["*.gif", "*.jpg", "*.png", "*.css", "*.js", "*.ico", "*.svg", "*woff*", "*.ttf"]</description>
      </parameter>
      <parameter name="scope_id" type="string" required="false">
        <description>Specific scope ID to operate on (required for get, update, delete)</description>
      </parameter>
      <parameter name="scope_name" type="string" required="false">
        <description>Name for scope (required for create, update)</description>
      </parameter>
    </parameters>
    <returns type="Dict[str, Any]">
      <description>Depending on action:
        - get: Single scope object or error
        - list: {"scopes": [...], "count": N}
        - create/update: {"scope": {...}, "message": "..."}
        - delete: {"message": "...", "deletedId": "..."}</description>
    </returns>
    <notes>
  - Empty allowlist = allow all domains
  - Denylist overrides allowlist
  - Glob patterns: * (any), ? (single), [abc] (one of), [a-z] (range), [^abc] (none of)
  - Each scope has unique ID and can be used with list_requests(scopeId=...)
    </notes>
    <examples>
  # Create API-only scope
  <function=scope_rules>
  <parameter=action>create</parameter>
  <parameter=scope_name>API Testing</parameter>
  <parameter=allowlist>["api.example.com", "*.api.com"]</parameter>
  <parameter=denylist>["*.gif", "*.jpg", "*.png", "*.css", "*.js"]</parameter>
  </function>
    </examples>
  </tool>

  <tool name="list_sitemap">
    <description>View hierarchical sitemap of discovered attack surface from proxied traffic.

    Perfect for bug hunters to understand the application structure and identify
    interesting endpoints, directories, and entry points discovered during testing.</description>
    <parameters>
      <parameter name="scope_id" type="string" required="false">
        <description>Scope ID to filter sitemap entries (use scope_rules to get/create scope IDs)</description>
      </parameter>
      <parameter name="parent_id" type="string" required="false">
        <description>ID of parent entry to expand. If None, returns root domains.</description>
      </parameter>
      <parameter name="depth" type="string" required="false">
        <description>DIRECT: Only immediate children. ALL: All descendants recursively.</description>
      </parameter>
      <parameter name="page" type="integer" required="false">
        <description>Page number for pagination (30 entries per page)</description>
      </parameter>
    </parameters>
    <returns type="Dict[str, Any]">
      <description>Response containing:
        - 'entries': List of cleaned sitemap entries
        - 'page', 'total_pages', 'total_count': Pagination info
        - 'has_more': Whether more pages available
        - Each entry: id, kind, label, hasDescendants, request (method/path/status only)</description>
    </returns>
    <notes>
  Entry kinds:
  - DOMAIN: Root domains (example.com)
  - DIRECTORY: Path directories (/api/, /admin/)
  - REQUEST: Individual endpoints
  - REQUEST_BODY: POST/PUT body variations
  - REQUEST_QUERY: GET parameter variations

  Check hasDescendants=true to identify entries worth expanding.
  Use parent_id from any entry to drill down into subdirectories.
    </notes>
  </tool>

  <tool name="view_sitemap_entry">
    <description>Get detailed information about a specific sitemap entry and related requests.

    Perfect for understanding what's been discovered under a specific directory
    or endpoint, including all related requests and response codes.</description>
    <parameters>
      <parameter name="entry_id" type="string" required="true">
        <description>ID of the sitemap entry to examine</description>
      </parameter>
    </parameters>
    <returns type="Dict[str, Any]">
      <description>Response containing:
        - 'entry': Complete entry details including metadata
        - Entry contains 'requests' with all related HTTP requests
        - Shows request methods, paths, response codes, timing</description>
    </returns>
  </tool>
</tools>
