addedOutput schema / $defs
Added value: +{
+ "AtlasTechniqueResponse": {
+ "additionalProperties": true,
+ "description": "MITRE ATLAS technique record (AI/ML attack catalog).\n\nATLAS catalogues adversarial techniques targeting AI/ML systems (LLM prompt\ninjection, model poisoning, evasion). About 80% of techniques have no ATT&CK\nbridge — ATLAS is the canonical reference for AI/ML-specific TTPs.",
+ "properties": {
+ "attack_reference_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Bridged ATT&CK technique id when ATLAS cites a parallel enterprise TTP, e.g. 'T1596'. About 20% of ATLAS techniques carry an ATT&CK reference; use this to pivot to D3FEND defenses.",
+ "title": "Attack Reference Id"
+ },
+ "attack_reference_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Canonical ATT&CK URL for the bridged technique, e.g. 'https://attack.mitre.org/techniques/T1596/'.",
+ "title": "Attack Reference Url"
+ },
+ "created_date": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "ISO-8601 date the technique was first published in ATLAS.",
+ "title": "Created Date"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Full technique description as published by MITRE ATLAS. May be multi-paragraph.",
+ "title": "Description"
+ },
+ "inherited_tactics": {
+ "anyOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "True when `tactics` was inherited from the parent technique (this is a sub-technique). Omitted when tactics are native to the record.",
+ "title": "Inherited Tactics"
+ },
+ "maturity": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "MITRE ATLAS maturity classification: 'demonstrated' (observed in real attacks) or 'feasible' (theoretical).",
+ "title": "Maturity"
+ },
+ "modified_date": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "ISO-8601 date of the most recent ATLAS update for this technique.",
+ "title": "Modified Date"
+ },
+ "name": {
+ "description": "Human-readable technique name, e.g. 'Search Open Technical Databases'.",
+ "title": "Name",
+ "type": "string"
+ },
+ "next_calls": {
+ "anyOf": [
+ {
+ "items": {
+ "$ref": "#/$defs/PivotHint"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Suggested follow-up MCP tool calls. Ordered by relevance; agents should chain these without re-prompting the user.",
+ "title": "Next Calls"
+ },
+ "subtechnique_of": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Parent technique id when this is a sub-technique, e.g. 'AML.T0000' for 'AML.T0000.000'.",
+ "title": "Subtechnique Of"
+ },
+ "tactics": {
+ "description": "ATLAS tactic ids that this technique belongs to, e.g. ['AML.TA0002'] (Reconnaissance). Sub-techniques have empty tactics in upstream ATLAS; we backfill from the parent and set inherited_tactics=true when this happens.",
+ "items": {
+ "type": "string"
+ },
+ "title": "Tactics",
+ "type": "array"
+ },
+ "technique_id": {
+ "description": "Canonical ATLAS technique id, e.g. 'AML.T0000', 'AML.T0000.000'.",
+ "title": "Technique Id",
+ "type": "string"
+ },
+ "verdict": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/Verdict"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Falsifiability metadata: sources_queried, sources_unavailable, completeness, deterministic flag. Lets agents distinguish 'no data' from 'source failed' without re-running the call."
+ }
+ },
+ "required": [
+ "technique_id",
+ "name"
+ ],
+ "title": "AtlasTechniqueResponse",
+ "type": "object"
+ },
+ "ErrorDetail": {
+ "description": "Structured failure body. Codes mirror app/exceptions.AppException\nsubclasses; agent retry / upgrade decisions key off `code`, not `message`.",
+ "properties": {
+ "code": {
+ "description": "Stable machine-readable failure category. Agents key retry/upgrade decisions off this.",
+ "enum": [
+ "invalid_argument",
+ "not_found",
+ "rate_limit_exceeded",
+ "auth_required",
+ "tier_limit",
+ "upstream_timeout",
+ "upstream_error",
+ "internal_error"
+ ],
+ "title": "Code",
+ "type": "string"
+ },
+ "docs_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Documentation pointer (e.g. tool input contract) when code='invalid_argument'.",
+ "title": "Docs Url"
+ },
+ "message": {
+ "description": "Human-readable detail. Free text — never parse. Capped at 500 chars to prevent oversized upstream errors from bloating responses.",
+ "maxLength": 500,
+ "title": "Message",
+ "type": "string"
+ },
+ "retry_after_seconds": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "When code='rate_limit_exceeded', the minimum seconds to wait before retrying.",
+ "title": "Retry After Seconds"
+ },
+ "upgrade_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Pricing/upgrade URL when code='tier_limit' or 'rate_limit_exceeded' on the Free tier.",
+ "title": "Upgrade Url"
+ }
+ },
+ "required": [
+ "code",
+ "message"
+ ],
+ "title": "ErrorDetail",
+ "type": "object"
+ },
+ "ErrorResponse": {
+ "description": "MCP error envelope. Tool return type is always\n`SpecificResponse | ErrorResponse` — Union flag tells the agent which arm\narrived without parsing the inner body.",
+ "properties": {
+ "error": {
+ "$ref": "#/$defs/ErrorDetail"
+ }
+ },
+ "required": [
+ "error"
+ ],
+ "title": "ErrorResponse",
+ "type": "object"
+ },
+ "PivotHint": {
+ "additionalProperties": true,
+ "description": "A suggested follow-up MCP tool call. Surfaced inside response.next_calls so\nLLM agents can chain related lookups without manual prompting. Each hint names\nthe tool, the input value to pass, and a short reason explaining why this\npivot adds value in the current context.",
+ "properties": {
+ "input": {
+ "description": "Suggested input value to pass to the tool — typically a CVE ID, CWE ID, domain, or IP. Pre-populated from the current response so the agent can call the next tool without re-deriving the argument.",
+ "title": "Input",
+ "type": "string"
+ },
+ "params": {
+ "anyOf": [
+ {
+ "additionalProperties": {
+ "type": "string"
+ },
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Optional extra kwargs to pass alongside `input`. Used by pivot generators when the next call benefits from a secondary parameter, e.g. {'exclude_id': 'AML.T0051'} to skip the originating technique from a sibling-tactic search. Omitted when no extra args are needed.",
+ "title": "Params"
+ },
+ "reason": {
+ "description": "Short rationale (one sentence) for why this follow-up call adds value, e.g. 'Federal patch deadline + ransomware association', 'Public exploits / PoC availability'.",
+ "title": "Reason",
+ "type": "string"
+ },
+ "tool": {
+ "description": "Canonical MCP tool name to call next. Constrained to known operation_ids in tools/list — adding a new tool here requires expanding the Literal.",
+ "enum": [
+ "cve_lookup",
+ "cve_search",
+ "cve_leading",
+ "bulk_cve_lookup",
+ "exploit_lookup",
+ "kev_detail",
+ "cwe_lookup",
+ "subdomain_enum",
+ "ssl_check",
+ "tech_fingerprint",
+ "asn_lookup",
+ "ip_lookup",
+ "ioc_lookup",
+ "bulk_ioc_lookup",
+ "hash_lookup",
+ "threat_intel",
+ "threat_report",
+ "audit_domain",
+ "domain_report",
+ "dns_lookup",
+ "whois_lookup",
+ "wayback_lookup",
+ "scan_headers",
+ "check_headers",
+ "check_secrets",
+ "check_injection",
+ "check_dependencies",
+ "email_mx",
+ "email_disposable",
+ "phone_lookup",
+ "username_lookup",
+ "password_check",
+ "phishing_check",
+ "atlas_technique_lookup",
+ "atlas_technique_search",
+ "bulk_atlas_technique_lookup",
+ "atlas_case_study_lookup",
+ "atlas_case_study_search",
+ "d3fend_defense_lookup",
+ "d3fend_defense_search",
+ "d3fend_defense_for_attack",
+ "d3fend_attack_coverage"
+ ],
+ "title": "Tool",
+ "type": "string"
+ }
+ },
+ "required": [
+ "tool",
+ "input",
+ "reason"
+ ],
+ "title": "PivotHint",
+ "type": "object"
+ },
+ "Verdict": {
+ "properties": {
+ "completeness": {
+ "default": "complete",
+ "description": "'complete' = every planned source returned data; 'partial' = at least one source in sources_unavailable failed or was skipped; 'minimal' = only the primary/required source returned, optional enrichment missing.",
+ "enum": [
+ "complete",
+ "partial",
+ "minimal"
+ ],
+ "title": "Completeness",
+ "type": "string"
+ },
+ "data_age_seconds": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Seconds elapsed since the oldest cached source was fetched, or null when every source was queried live for this request. Use to judge freshness.",
+ "title": "Data Age Seconds"
+ },
+ "deterministic": {
+ "description": "True when the response is fully reproducible from the listed sources for the same input at the same moment (no randomness, no model inference). False for endpoints that include probabilistic scoring or LLM output.",
+ "title": "Deterministic",
+ "type": "boolean"
+ },
+ "falsifiable_fields": {
+ "description": "Top-level response fields whose values a caller can independently re-derive from the named upstream sources (e.g. 'dns', 'ssl', 'whois'). Fields not in this list are derived/computed and cannot be directly re-verified.",
+ "items": {
+ "type": "string"
+ },
+ "title": "Falsifiable Fields",
+ "type": "array"
+ },
+ "sources_queried": {
+ "description": "Canonical source identifiers successfully consulted for this response (e.g. 'ripe_stat', 'shodan_internetdb', 'firehol'). Agent-readable list, order not significant.",
+ "items": {
+ "type": "string"
+ },
+ "title": "Sources Queried",
+ "type": "array"
+ },
+ "sources_unavailable": {
+ "description": "Sources that were expected but not returned — either intentionally skipped (lite mode, tier gating) or failed (quota, timeout, upstream down). Empty list means every planned source produced data.",
+ "items": {
+ "type": "string"
+ },
+ "title": "Sources Unavailable",
+ "type": "array"
+ }
+ },
+ "required": [
+ "deterministic"
+ ],
+ "title": "Verdict",
+ "type": "object"
+ }
+}