misp_add_sighting
Report a sighting of an IOC to confirm it was observed in the wild, mark it as false positive, or set its expiration.
Instructions
Report a sighting of an IOC (confirms it was observed in the wild, marks as false positive, or sets expiration)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| attributeId | No | Attribute ID to sight (use this or value) | |
| value | No | Attribute value to sight (use this or attributeId) | |
| type | Yes | 0=Sighting (seen in the wild), 1=False positive, 2=Expiration | |
| source | No | Source of the sighting (e.g., organization name, sensor ID) | |
| timestamp | No | Timestamp of the sighting (Unix timestamp) |
Implementation Reference
- src/tools/sightings.ts:17-66 (handler)The tool handler function for 'misp_add_sighting'. Takes params (attributeId, value, type, source, timestamp), calls client.addSighting(), and returns a formatted response with sighting details or an error.
async (params) => { try { if (!params.attributeId && !params.value) { return { content: [ { type: "text", text: "Either attributeId or value must be provided." }, ], isError: true, }; } const sighting = await client.addSighting({ attributeId: params.attributeId, value: params.value, type: params.type, source: params.source, timestamp: params.timestamp, }); const typeLabels = ["Sighting", "False positive", "Expiration"]; return { content: [ { type: "text", text: JSON.stringify( { id: sighting.id, type: typeLabels[params.type], attribute_id: sighting.attribute_id, event_id: sighting.event_id, source: sighting.source, date_sighting: sighting.date_sighting, }, null, 2 ), }, ], }; } catch (err) { return { content: [ { type: "text", text: `Error adding sighting: ${err instanceof Error ? err.message : String(err)}` }, ], isError: true, }; } } ); - src/tools/sightings.ts:9-16 (schema)Input schema for misp_add_sighting: attributeId (optional), value (optional), type (0|1|2 for Sighting/False positive/Expiration), source (optional), timestamp (optional).
{ attributeId: z.string().optional().describe("Attribute ID to sight (use this or value)"), value: z.string().optional().describe("Attribute value to sight (use this or attributeId)"), type: z.union([z.literal(0), z.literal(1), z.literal(2)]) .describe("0=Sighting (seen in the wild), 1=False positive, 2=Expiration"), source: z.string().optional().describe("Source of the sighting (e.g., organization name, sensor ID)"), timestamp: z.string().optional().describe("Timestamp of the sighting (Unix timestamp)"), }, - src/tools/sightings.ts:5-67 (registration)Registration function 'registerSightingTools' which calls server.tool() to register 'misp_add_sighting' on the MCP server.
export function registerSightingTools(server: McpServer, client: MispClient): void { server.tool( "misp_add_sighting", "Report a sighting of an IOC (confirms it was observed in the wild, marks as false positive, or sets expiration)", { attributeId: z.string().optional().describe("Attribute ID to sight (use this or value)"), value: z.string().optional().describe("Attribute value to sight (use this or attributeId)"), type: z.union([z.literal(0), z.literal(1), z.literal(2)]) .describe("0=Sighting (seen in the wild), 1=False positive, 2=Expiration"), source: z.string().optional().describe("Source of the sighting (e.g., organization name, sensor ID)"), timestamp: z.string().optional().describe("Timestamp of the sighting (Unix timestamp)"), }, async (params) => { try { if (!params.attributeId && !params.value) { return { content: [ { type: "text", text: "Either attributeId or value must be provided." }, ], isError: true, }; } const sighting = await client.addSighting({ attributeId: params.attributeId, value: params.value, type: params.type, source: params.source, timestamp: params.timestamp, }); const typeLabels = ["Sighting", "False positive", "Expiration"]; return { content: [ { type: "text", text: JSON.stringify( { id: sighting.id, type: typeLabels[params.type], attribute_id: sighting.attribute_id, event_id: sighting.event_id, source: sighting.source, date_sighting: sighting.date_sighting, }, null, 2 ), }, ], }; } catch (err) { return { content: [ { type: "text", text: `Error adding sighting: ${err instanceof Error ? err.message : String(err)}` }, ], isError: true, }; } } ); } - src/client.ts:365-386 (helper)Client helper method 'addSighting' that sends a POST request to /sightings/add (optionally with attribute ID in the path) with the sighting payload, and returns the MispSighting response.
async addSighting(params: { attributeId?: string; value?: string; type: number; source?: string; timestamp?: string; }): Promise<MispSighting> { const body: Record<string, unknown> = { type: params.type, }; if (params.value) body.value = params.value; if (params.source) body.source = params.source; if (params.timestamp) body.timestamp = params.timestamp; const path = params.attributeId ? `/sightings/add/${encodeId(params.attributeId, "attributeId")}` : "/sightings/add"; const data = await this.request<{ Sighting: MispSighting }>("POST", path, body); return data.Sighting; } - src/types.ts:170-178 (helper)MispSighting interface defining the shape of the sighting response (id, attribute_id, event_id, org_id, date_sighting, source, type).
export interface MispSighting { id: string; attribute_id: string; event_id: string; org_id: string; date_sighting: string; source: string; type: string; }