Phishing Investigator Autogen
What it does
Three analysts run in parallel on a reported email: a header analyst reads the auth and routing, a link analyst opens the URLs in a sandboxed browser and checks their reputation, and an attachment analyst scans payloads against threat intelligence. A prosecutor and a defender then debate the evidence to a verdict, which suppresses false alarms. A confirmed-malicious verdict is packaged with its evidence and paused for a human to approve remediation. Nothing is quarantined without sign-off.
The cast · 6 agents
Argue that the email is benign, challenging weak or circumstantial evidence. Return an object with a 'malicious' boolean and a confidence level representing where the debate settled. Default to malicious only when the evidence is clear; flag genuine uncertainty for a human.
Package the verdict and the evidence into a short case for the security channel. If malicious, list the recommended remediation (quarantine, block sender, reset if credentials were entered). Do not execute any remediation.
Argue that the email is malicious, citing the strongest evidence from the three analysts. If you received a defender rebuttal, sharpen or concede specific points honestly.
Open each link in the sandboxed browser and check its reputation. Report the final landing domain, any credential-harvest form, redirects, and the reputation verdict. Never enter credentials or submit forms.
Read the email headers. Report SPF, DKIM, and DMARC results, the true sending path, and any display-name or reply-to mismatch. Facts only.
Scan each attachment against threat intelligence. Report file type, hash reputation, and any macro or executable content. Do not execute attachments.
Flow
Interface
Depends on · 4 MCP servers
Multi-account MCP for Gmail, Calendar, Drive, Docs, and Sheets — 61 tools, tokenio.github.adelaidasofia/google-workspace-mcpmailAVerified
Playwrightio.github.microsoft/playwright-mcpbrowserBVerified
Virustotalio.github.BurtTheCoder/virustotalintelAVerified
io.github.slack/slack-mcpnot in the registry yetchat# Generated by @socketcat/compiler for target: langgraph
# blueprint: com.socketcat/phishing-investigator v1.0.0 schema: socketcat.dev/blueprint/v0
# This code is yours. Edit it freely. The socketcat_runtime helper is optional and can be vendored.
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
import socketcat_runtime as _rt
class State(TypedDict, total=False):
reportedEmail: object
disposition: object
headerFindings: object
linkFindings: object
fileFindings: object
__loop_5: object
verdict: object
def node_Fork_0(state):
return {}
def node_Join_1(state):
return {}
def node_AgentInvoke_2(state):
return _rt.run_agent("headerAnalyst", state, {"reportedEmail":"reportedEmail"}, "headerFindings")
def node_AgentInvoke_3(state):
return _rt.run_agent("linkAnalyst", state, {"reportedEmail":"reportedEmail"}, "linkFindings")
def node_AgentInvoke_4(state):
return _rt.run_agent("attachmentAnalyst", state, {"reportedEmail":"reportedEmail"}, "fileFindings")
def node_LoopHeader_5(state):
return {}
def node_LoopTick_6(state):
return {"__loop_5": state.get("__loop_5", 0) + 1}
def node_Nop_7(state):
return {}
def node_AgentInvoke_8(state):
return _rt.run_agent("prosecutor", state, {"verdict":"verdict","fileFindings":"fileFindings","linkFindings":"linkFindings","headerFindings":"headerFindings"}, "verdict")
def node_AgentInvoke_9(state):
return _rt.run_agent("defender", state, {"verdict":"verdict","fileFindings":"fileFindings","linkFindings":"linkFindings","headerFindings":"headerFindings"}, "verdict")
def node_AgentInvoke_10(state):
return _rt.run_agent("packager", state, {"verdict":"verdict"}, "disposition")
def node_Ask_11(state):
return _rt.run_ask("Review the phishing verdict and evidence. Approve remediation, or dismiss as benign.", state, "disposition")
def route_LoopHeader_5(state):
count = state.get("__loop_5", 0)
return "exit" if (_rt.cond("verdict.malicious != null", state) or count >= 2) else "loop"
def build():
b = StateGraph(State)
b.add_node("Fork_0", node_Fork_0)
b.add_node("Join_1", node_Join_1)
b.add_node("AgentInvoke_2", node_AgentInvoke_2)
b.add_node("AgentInvoke_3", node_AgentInvoke_3)
b.add_node("AgentInvoke_4", node_AgentInvoke_4)
b.add_node("LoopHeader_5", node_LoopHeader_5)
b.add_node("LoopTick_6", node_LoopTick_6)
b.add_node("Nop_7", node_Nop_7)
b.add_node("AgentInvoke_8", node_AgentInvoke_8)
b.add_node("AgentInvoke_9", node_AgentInvoke_9)
b.add_node("AgentInvoke_10", node_AgentInvoke_10)
b.add_node("Ask_11", node_Ask_11)
b.add_edge(START, "Fork_0")
b.add_edge("Fork_0", "AgentInvoke_2")
b.add_edge("Fork_0", "AgentInvoke_3")
b.add_edge("Fork_0", "AgentInvoke_4")
b.add_edge("Join_1", "AgentInvoke_8")
b.add_edge("AgentInvoke_2", "Join_1")
b.add_edge("AgentInvoke_3", "Join_1")
b.add_edge("AgentInvoke_4", "Join_1")
b.add_conditional_edges("LoopHeader_5", route_LoopHeader_5, {"loop": "AgentInvoke_8", "exit": "Nop_7"})
b.add_edge("LoopTick_6", "LoopHeader_5")
b.add_edge("Nop_7", "AgentInvoke_10")
b.add_edge("AgentInvoke_8", "AgentInvoke_9")
b.add_edge("AgentInvoke_9", "LoopTick_6")
b.add_edge("AgentInvoke_10", "Ask_11")
b.add_edge("Ask_11", END)
return b.compile()
INPUTS = ["reportedEmail"]
OUTPUTS = ["disposition"]
if __name__ == "__main__":
_rt.main(build, INPUTS, OUTPUTS)
▸blueprint.json (the portable format)
{
"id": "com.socketcat/phishing-investigator",
"flow": {
"type": "sequence",
"blocks": [
{
"type": "parallel",
"blocks": [
{
"in": {
"reportedEmail": "reportedEmail"
},
"out": "headerFindings",
"use": "headerAnalyst",
"type": "agent"
},
{
"in": {
"reportedEmail": "reportedEmail"
},
"out": "linkFindings",
"use": "linkAnalyst",
"type": "agent"
},
{
"in": {
"reportedEmail": "reportedEmail"
},
"out": "fileFindings",
"use": "attachmentAnalyst",
"type": "agent"
}
]
},
{
"max": 2,
"type": "loop",
"until": "verdict.malicious != null",
"blocks": [
{
"in": {
"verdict": "verdict",
"fileFindings": "fileFindings",
"linkFindings": "linkFindings",
"headerFindings": "headerFindings"
},
"out": "verdict",
"use": "prosecutor",
"type": "agent"
},
{
"in": {
"verdict": "verdict",
"fileFindings": "fileFindings",
"linkFindings": "linkFindings",
"headerFindings": "headerFindings"
},
"out": "verdict",
"use": "defender",
"type": "agent"
}
]
},
{
"in": {
"verdict": "verdict"
},
"out": "disposition",
"use": "packager",
"type": "agent"
},
{
"out": "disposition",
"type": "ask",
"prompt": "Review the phishing verdict and evidence. Approve remediation, or dismiss as benign."
}
]
},
"tags": [
"security",
"phishing",
"debate",
"human-in-the-loop"
],
"title": "Phishing Investigator",
"agents": {
"defender": {
"model": {
"hint": "reasoning"
},
"title": "Defender",
"output": {
"type": "object",
"required": [
"malicious"
],
"properties": {
"malicious": {
"type": "boolean"
},
"rationale": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"instructions": "Argue that the email is benign, challenging weak or circumstantial evidence. Return an object with a 'malicious' boolean and a confidence level representing where the debate settled. Default to malicious only when the evidence is clear; flag genuine uncertainty for a human."
},
"packager": {
"model": {
"hint": "fast"
},
"title": "Packager",
"tools": [
"chat.post_message"
],
"instructions": "Package the verdict and the evidence into a short case for the security channel. If malicious, list the recommended remediation (quarantine, block sender, reset if credentials were entered). Do not execute any remediation."
},
"prosecutor": {
"model": {
"hint": "reasoning"
},
"title": "Prosecutor",
"instructions": "Argue that the email is malicious, citing the strongest evidence from the three analysts. If you received a defender rebuttal, sharpen or concede specific points honestly."
},
"linkAnalyst": {
"model": {
"hint": "reasoning"
},
"title": "Link Analyst",
"tools": [
"browser.open",
"intel.url_report"
],
"instructions": "Open each link in the sandboxed browser and check its reputation. Report the final landing domain, any credential-harvest form, redirects, and the reputation verdict. Never enter credentials or submit forms."
},
"headerAnalyst": {
"model": {
"hint": "fast"
},
"title": "Header Analyst",
"tools": [
"mail.get_message"
],
"instructions": "Read the email headers. Report SPF, DKIM, and DMARC results, the true sending path, and any display-name or reply-to mismatch. Facts only."
},
"attachmentAnalyst": {
"model": {
"hint": "fast"
},
"title": "Attachment Analyst",
"tools": [
"intel.file_report"
],
"instructions": "Scan each attachment against threat intelligence. Report file type, hash reputation, and any macro or executable content. Do not execute attachments."
}
},
"estate": {
"verdict": {
"type": "object",
"description": "The debate's verdict, including a 'malicious' flag and confidence."
},
"fileFindings": {
"type": "object",
"description": "The attachment analyst's payload scan."
},
"linkFindings": {
"type": "object",
"description": "The link analyst's detonation and reputation results."
},
"headerFindings": {
"type": "object",
"description": "The header analyst's auth and routing read."
}
},
"$schema": "socketcat.dev/blueprint/v0",
"authors": [
{
"url": "https://socketcat.com",
"name": "SocketCat"
}
],
"license": "MIT",
"servers": [
{
"ref": "io.github.adelaidasofia/google-workspace-mcp",
"alias": "mail"
},
{
"ref": "io.github.microsoft/playwright-mcp",
"alias": "browser"
},
{
"ref": "io.github.BurtTheCoder/virustotal",
"alias": "intel"
},
{
"ref": "io.github.slack/slack-mcp",
"alias": "chat"
}
],
"summary": "Analyzes a reported email from three angles in parallel, debates benign vs. malicious to a verdict, and pauses for human remediation.",
"targets": [
"*"
],
"version": "1.0.0",
"interface": {
"inputs": {
"reportedEmail": {
"type": "object",
"description": "The user-reported email: raw source or a message id."
}
},
"outputs": {
"disposition": {
"type": "string",
"description": "The verdict and, if malicious, the approved remediation package."
}
}
},
"extensions": {
"com.autogen": {
"chat": "group"
}
},
"description": "Three analysts run in parallel on a reported email: a header analyst reads the auth and routing, a link analyst opens the URLs in a sandboxed browser and checks their reputation, and an attachment analyst scans payloads against threat intelligence. A prosecutor and a defender then debate the evidence to a verdict, which suppresses false alarms. A confirmed-malicious verdict is packaged with its evidence and paused for a human to approve remediation. Nothing is quarantined without sign-off."
}