poll_interactsh_session
Retrieve and decrypt security testing interactions for a session, with optional filters for HTTP method, path, query, protocol, or text content.
Instructions
Retrieves and decrypts interactions for a session. Optional filters let you match HTTP method, path, query, protocol, or free text.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| correlation_id | Yes | ||
| method | No | ||
| path_contains | No | ||
| query_contains | No | ||
| protocol | No | ||
| text_contains | No |
Implementation Reference
- src/server.js:342-375 (registration)Registration of the 'poll_interactsh_session' MCP tool, defining metadata, Zod inputSchema, and inline handler function that delegates to service.pollSession and applies filters.server.registerTool( 'poll_interactsh_session', { title: 'Poll session', description: 'Retrieves and decrypts interactions for a session. Optional filters let you match HTTP method, path, query, protocol, or free text.', inputSchema: { correlation_id: z.string(), method: z.string().optional(), path_contains: z.string().optional(), query_contains: z.string().optional(), protocol: z.string().optional(), text_contains: z.string().optional(), }, }, async ({ correlation_id, ...filters }) => { const payload = await service.pollSession(correlation_id); const sanitizedFilters = Object.fromEntries( Object.entries(filters) .filter(([, value]) => value !== undefined && value !== '') .map(([key, value]) => [key, typeof value === 'string' ? value : JSON.stringify(value)]), ); const filteredEvents = applyEventFilters(payload.events, sanitizedFilters); return result({ applied_filters: sanitizedFilters, total_events: payload.events.length, matched_events: filteredEvents.length, events: filteredEvents, extra: payload.extra, tld_data: payload.tld_data, }); }, );
- src/server.js:348-355 (schema)Zod input schema for the tool: requires correlation_id, optional filter fields (method, path_contains, query_contains, protocol, text_contains).inputSchema: { correlation_id: z.string(), method: z.string().optional(), path_contains: z.string().optional(), query_contains: z.string().optional(), protocol: z.string().optional(), text_contains: z.string().optional(), },
- src/server.js:357-374 (handler)Inline MCP tool handler: calls service.pollSession, sanitizes and applies filters to events, returns structured content with counts and filtered results.async ({ correlation_id, ...filters }) => { const payload = await service.pollSession(correlation_id); const sanitizedFilters = Object.fromEntries( Object.entries(filters) .filter(([, value]) => value !== undefined && value !== '') .map(([key, value]) => [key, typeof value === 'string' ? value : JSON.stringify(value)]), ); const filteredEvents = applyEventFilters(payload.events, sanitizedFilters); return result({ applied_filters: sanitizedFilters, total_events: payload.events.length, matched_events: filteredEvents.length, events: filteredEvents, extra: payload.extra, tld_data: payload.tld_data, }); },
- src/server.js:73-88 (handler)Core InteractshService.pollSession method: authenticates and GET /poll endpoint, decrypts events using session's private key, normalizes extra/tld_data.async pollSession(correlationId) { const session = this.#requireSession(correlationId); const url = new URL('/poll', this.baseUrl); url.searchParams.set('id', session.correlationId); url.searchParams.set('secret', session.secretKey); const response = await this.#request(url, { method: 'GET' }); const payload = await response.json(); const events = this.#decryptEvents(session.privateKey, payload); return { events, extra: normaliseArray(payload.extra), tld_data: normaliseArray(payload.tlddata), }; }
- src/server.js:197-242 (helper)Helper function to filter decrypted events by HTTP method, protocol, path/query contains, or free-text search across raw/parsed data.function applyEventFilters(events, filters) { if (!events.length) { return []; } const methodFilter = filters.method ? filters.method.toUpperCase() : undefined; const protocolFilter = filters.protocol ? filters.protocol.toLowerCase() : undefined; const pathFilter = filters.path_contains ? filters.path_contains.toLowerCase() : undefined; const queryFilter = filters.query_contains ? filters.query_contains.toLowerCase() : undefined; const textFilter = filters.text_contains ? filters.text_contains.toLowerCase() : undefined; return events .map((raw) => { const parsed = parseEvent(raw); return { raw, ...parsed }; }) .filter(({ raw, parsed, http, protocol }) => { if (methodFilter && (!http || http.method !== methodFilter)) { return false; } if (pathFilter && (!http || !http.pathLower.includes(pathFilter))) { return false; } if (queryFilter && (!http || !http.queryLower.includes(queryFilter))) { return false; } if (protocolFilter && (!protocol || protocol.toLowerCase() !== protocolFilter)) { return false; } if (textFilter) { const haystack = [raw, parsed ? JSON.stringify(parsed) : '', http?.fullPath ?? ''] .join(' ') .toLowerCase(); if (!haystack.includes(textFilter)) { return false; } } return true; }) .map(({ raw, parsed, http, protocol }) => ({ raw, protocol: protocol ?? undefined, http: http ?? undefined, parsed: parsed ?? undefined, })); }