misp_correlate
Find all MISP events containing a given observable value (IP, domain, hash, etc.) to identify correlations and related threat intelligence.
Instructions
Find correlations for a specific observable value across all MISP events
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | Observable value to correlate (IP, domain, hash, etc.) |
Implementation Reference
- src/tools/correlation.ts:7-83 (handler)The main handler for the 'misp_correlate' tool. It accepts a 'value' parameter (observable value like IP, domain, hash, etc.), searches MISP attributes using searchAttributes with includeCorrelations=true, aggregates results by event, collects related attribute correlations, and returns a JSON response with found events and cross-event correlations.
server.tool( "misp_correlate", "Find correlations for a specific observable value across all MISP events", { value: z.string().describe("Observable value to correlate (IP, domain, hash, etc.)"), }, async ({ value }) => { try { const attributes = await client.searchAttributes({ value, includeCorrelations: true, }); if (attributes.length === 0) { return { content: [{ type: "text", text: `No results found for "${value}" in MISP.` }], }; } // Aggregate by event const eventMap = new Map< string, { event_id: string; event_info: string; attributes: Array<{ id: string; type: string; category: string; value: string }> } >(); for (const attr of attributes) { const eid = attr.event_id; if (!eventMap.has(eid)) { eventMap.set(eid, { event_id: eid, event_info: attr.Event?.info || "Unknown", attributes: [], }); } eventMap.get(eid)!.attributes.push({ id: attr.id, type: attr.type, category: attr.category, value: attr.value, }); } // Collect related attributes (correlations) const correlations: Array<{ value: string; type: string; event_id: string }> = []; for (const attr of attributes) { if (attr.RelatedAttribute) { for (const rel of attr.RelatedAttribute) { correlations.push({ value: rel.value, type: rel.type, event_id: rel.event_id, }); } } } const result = { searched_value: value, found_in_events: Array.from(eventMap.values()), total_events: eventMap.size, total_attributes: attributes.length, correlations: correlations.length > 0 ? correlations : undefined, }; return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; } catch (err) { return { content: [ { type: "text", text: `Error correlating value: ${err instanceof Error ? err.message : String(err)}` }, ], isError: true, }; } } ); - src/tools/correlation.ts:10-12 (schema)Input schema for 'misp_correlate'. Defines a single required parameter 'value' of type string, described as 'Observable value to correlate (IP, domain, hash, etc.)'.
{ value: z.string().describe("Observable value to correlate (IP, domain, hash, etc.)"), }, - src/tools/correlation.ts:5-83 (registration)The 'misp_correlate' tool is registered via server.tool() inside the registerCorrelationTools() function in src/tools/correlation.ts. This function is called from src/index.ts line 33.
export function registerCorrelationTools(server: McpServer, client: MispClient): void { // Correlate an observable value server.tool( "misp_correlate", "Find correlations for a specific observable value across all MISP events", { value: z.string().describe("Observable value to correlate (IP, domain, hash, etc.)"), }, async ({ value }) => { try { const attributes = await client.searchAttributes({ value, includeCorrelations: true, }); if (attributes.length === 0) { return { content: [{ type: "text", text: `No results found for "${value}" in MISP.` }], }; } // Aggregate by event const eventMap = new Map< string, { event_id: string; event_info: string; attributes: Array<{ id: string; type: string; category: string; value: string }> } >(); for (const attr of attributes) { const eid = attr.event_id; if (!eventMap.has(eid)) { eventMap.set(eid, { event_id: eid, event_info: attr.Event?.info || "Unknown", attributes: [], }); } eventMap.get(eid)!.attributes.push({ id: attr.id, type: attr.type, category: attr.category, value: attr.value, }); } // Collect related attributes (correlations) const correlations: Array<{ value: string; type: string; event_id: string }> = []; for (const attr of attributes) { if (attr.RelatedAttribute) { for (const rel of attr.RelatedAttribute) { correlations.push({ value: rel.value, type: rel.type, event_id: rel.event_id, }); } } } const result = { searched_value: value, found_in_events: Array.from(eventMap.values()), total_events: eventMap.size, total_attributes: attributes.length, correlations: correlations.length > 0 ? correlations : undefined, }; return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; } catch (err) { return { content: [ { type: "text", text: `Error correlating value: ${err instanceof Error ? err.message : String(err)}` }, ], isError: true, }; } } ); - src/client.ts:257-287 (helper)The searchAttributes method on MispClient that the misp_correlate handler calls. It POSTs to /attributes/restSearch with optional filters like value, type, category, tags, to_ids, includeCorrelations, last, and limit.
async searchAttributes(params: { value?: string; type?: string; category?: string; tags?: string[]; to_ids?: boolean; includeCorrelations?: boolean; last?: string; limit?: number; }): Promise<MispAttribute[]> { const body: Record<string, unknown> = { returnFormat: "json", limit: params.limit ?? 50, }; if (params.value) body.value = params.value; if (params.type) body.type = params.type; if (params.category) body.category = params.category; if (params.tags) body.tags = params.tags; if (params.to_ids !== undefined) body.to_ids = params.to_ids ? 1 : 0; if (params.includeCorrelations) body.includeCorrelations = 1; if (params.last) body.last = params.last; const data = await this.request<AttributeSearchResponse>( "POST", "/attributes/restSearch", body ); return data.response?.Attribute || []; } - src/index.ts:33-33 (registration)The top-level registration call: registerCorrelationTools(server, client) which wires the misp_correlate tool into the MCP server.
registerCorrelationTools(server, client);