Intel Threadlinqs MCP
The Intel Threadlinqs MCP server provides 49 tools across threat intelligence, detection engineering, IOC analysis, threat actors, MITRE ATT&CK, C2 infrastructure, and composite Purple-tier workflows.
Threat Intelligence
Search/browse 583+ threats by severity, actor, CVE, MITRE technique, sector, malware, campaign, date, etc.
Get full threat details: metadata, CVSS, attribution, CVEs/CWEs, MITRE mappings, IOCs, detections
Bulk fetch up to 20 threats in one call; get enrichment, similar threats, and analysis transcripts
(Purple) Threat hunting bundle: threat detail + IOCs + detections + simulations + infrastructure pivots in one call
Detection Rules
Search/list 5,700+ rules in Splunk SPL, Microsoft KQL, and Sigma YAML
Get full rule content, MITRE mappings, data sources, and false positive guidance
Export rules in SPL, KQL, Sigma YAML, or JSON
IOCs & Enrichment
Search 16,500+ indicators (IPs, domains, hashes, URLs, behavioral)
Live enrichment via ThreatFox, MalwareBazaar, AbuseIPDB, and passive DNS
(Purple) IOC intelligence: full dossier with threat/actor attribution, DNS trail, infrastructure pivots, and 7-feed consensus score
Threat Actors
Search 334+ actors by name, alias, nation-state, or motivation
Get actor profiles: TTPs, attributed threats, MITRE rollup, IOC counts
(Purple) Composite actor intelligence: profile + active C2 + cross-actor shared entities + activity timeline
MITRE ATT&CK
Coverage stats across all techniques/tactics with detection counts
Technique detail: mitigations, data sources, linked threats
(Purple) Gap analysis: prioritized uncovered techniques by detection debt score
(Purple) Attack path prediction based on 4,271+ observed technique transitions
C2 Infrastructure
List/analyze 140+ live Cobalt Strike beacons: configs, watermarks, geolocation, operator fingerprints
C2 timeline, cross-correlations, and behavioral clustering
(Purple) Generate firewall-ready IP blocklists by framework, recency, and format
CVE & CWE Intelligence
CVE/CWE details with CVSS, affected products, linked threats, and mitigations
(Purple) CVE intelligence: EPSS velocity, KEV status, exploitation timeline, detection coverage
Daily Intelligence & Correlations
Daily debriefs, recent threats, and full daily intel bundles
7 correlation engines: MITRE heatmap, adversary infrastructure, IOC consensus, CVE velocity, attribution network, detection debt, enrichment health
Pivoting & Entity Resolution
Pivot on malware families, offensive tools, or named campaigns
Normalize actor/malware/tool aliases to canonical forms
Utilities
Health check, platform stats, enrichment overview, changelog, and roadmap
Provides Splunk SPL detection rules for threat detection and hunting across the threat intelligence corpus.
intelthreadlinqs-mcp
MCP server for Threadlinqs Intelligence — 81 tools and 25 analyst-playbook prompts across threat intelligence, detections, IOCs, threat actors, MITRE attack-chains, C2 infrastructure, and Purple-tier composite intelligence. Drop-in for Claude Code, Claude Desktop, Cursor, and any MCP-compatible client.
What this gives your AI agent
1,700+ threats with full metadata, severity, attribution, CVE/CWE, MITRE
16,000+ detection rules in Splunk SPL, Microsoft KQL, and Sigma YAML
47,000+ IOCs (IPs, domains, hashes, URLs, behavioral)
500+ threat actors with TTPs profiles and cross-actor infrastructure links
140+ live C2 beacons (Cobalt Strike) with watermark clustering + operator attribution
Daily intelligence debriefs + 7-engine correlation analytics
MITRE attack-chain prediction based on 4,271 observed technique transitions
Related MCP server: Cooper Cyber Coffee OpenCTI MCP Server
Quick install
# No install needed — npx will fetch it
npx -y intelthreadlinqs-mcpClaude Code
claude mcp add threadlinqs-intel \
-e THREADLINQS_API_KEY=tl_your_key_here \
-- npx -y intelthreadlinqs-mcpThe -e THREADLINQS_API_KEY is required in practice. The Threadlinqs Intelligence MCP server is a Purple-tier feature — it checks your key's tier at startup and warns if it is missing, invalid, or below Purple. The server still starts and exposes its tool catalog so clients and registries can introspect it, but tool calls are gated server-side: without a Purple or Gold key (tier ≥ 3) they return an Access denied error instead of data. There is no free or anonymous access to gated intelligence.
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"threadlinqs-intel": {
"command": "npx",
"args": ["-y", "intelthreadlinqs-mcp"],
"env": {
"THREADLINQS_API_KEY": "tl_your_key_here"
}
}
}
}Cursor
.cursor/mcp.json:
{
"mcpServers": {
"threadlinqs-intel": {
"command": "npx",
"args": ["-y", "intelthreadlinqs-mcp"],
"env": {
"THREADLINQS_API_KEY": "tl_your_key_here"
}
}
}
}VS Code
.vscode/mcp.json:
{
"servers": {
"threadlinqs-intel": {
"type": "stdio",
"command": "npx",
"args": ["-y", "intelthreadlinqs-mcp"],
"env": {
"THREADLINQS_API_KEY": "tl_your_key_here"
}
}
}
}Getting an API key
Sign up at intel.threadlinqs.com, verify your email, and head to Profile → API Key. Note that signing up alone lands you on Blue (tier 1) — MCP tool calls need tier ≥ 3, so they return an under-tier error until you upgrade. A 7-day Purple free trial is offered at checkout on the pricing page.
Access — Purple tier only
The MCP server is a Purple-tier feature: all 81 tools require a Purple or Gold subscription (tier ≥ 3). The server checks your key's tier at startup and warns when it is missing, invalid, or below Purple — it still starts and lists its tools so clients can introspect the catalog, but the tier is enforced server-side on every call, so gated tools return Access denied rather than data. There is no free or anonymous access to gated intelligence.
Tier | Price | MCP access |
Purple | $11.99/mo | ✅ All 81 tools |
Gold | Custom | ✅ All 81 tools (team — contact sales) |
Lower tiers | — | ❌ No MCP access (the public website + REST API keep their own free Blue tier) |
A 7-day Purple free trial is available at checkout on the pricing page — it is not granted by signup alone. Tool calls enforce the tier server-side and return a structured 403 if your subscription lapses.
v4.3 flagship tools (Purple tier)
The composite tools are the reason most people upgrade to Purple — each one replaces 5–7 single-purpose MCP calls.
get_threat_hunting_bundle ⭐
Input: threat_id (e.g. "TL-2026-0599")
Returns: complete hunt dossier in one shot — threat metadata, full IOC list, SPL/KQL/Sigma detection queries, similar threats, simulation commands, and cross-threat infrastructure pivots. The single most useful tool in the platform.
get_actor_intelligence
Input: actor name (e.g. "Lazarus Group", "APT29")
Returns: comprehensive adversary picture — actor profile, attributed threats, MITRE techniques, IOCs (200 cap), detection rules (100 cap), activity timeline, active C2 infrastructure correlated to the actor, and cross-actor shared entities.
get_ioc_intelligence
Input: ioc_value (IP, domain, hash, URL)
Returns: every threat that touches the IOC + actor attribution + DNS enrichment trail + cross-IOC infrastructure pivots + consensus confidence score across 7 external feeds (Pulsedive, GreyNoise, YARAify, MalwareBazaar, URLScan, VxVault, OpenPhish). The "I found this in a log — tell me everything" workflow.
get_cve_intelligence
Input: cve_id (e.g. "CVE-2024-3400")
Returns: CVE detail + linked threats + EPSS exploitation velocity + KEV status + detection coverage % + available attack simulations + first-weaponization timeline.
get_mitre_gap_analysis
Input: optional tactic filter, limit
Returns: prioritized list of MITRE techniques without detection coverage, sorted by debt score (threat exposure + KEV count + EPSS). Each entry includes example threats and recommended detection types. Answers "what should I write detections for next?"
predict_mitre_transitions
Input: technique_id (e.g. "T1566"), top_n, direction (forward | reverse)
Returns: ranked next-technique predictions with probability and observation count, plus example threats showing the chain. Built from 4,271 observed transitions across the corpus.
generate_c2_blocklist
Input: none.
Returns: firewall-ready blocklist of active C2 IPs with country, ASN, version, watermark, and last-seen metadata. Currently tracking Cobalt Strike beacons. For operator clustering call get_c2, and for unmasked C2 domains get_c2_dns_intel.
Specialized tools
search_actors— Find threat actors by name, alias, nation-state, or motivation.get_actor— Full actor dossier in a single call.get_similar_threats— Precomputed-similarity matches by shared TTPs, IOC overlap, and same-actor attribution.
Agent skill
A portable skill that teaches any MCP client how to route across these tools — which tool to
call first, the hunt query grammar, the response budget, and the data caveats that keep
answers honest. Generated from the live catalog, so its tool reference cannot drift.
Single file (paste into any assistant): https://intel.threadlinqs.com/mcp/skill.md
Bundle (
SKILL.md+references/, for Claude Desktop / API skill upload): https://intel.threadlinqs.com/skills/intelthreadlinqs-mcp-skill.zipAlso in this repo under
skill/, and linked from https://intel.threadlinqs.com/mcp.
Prompts — 25 analyst playbooks
Prompts are pre-built workflows that orchestrate the tools for you. Rather than working out which of 81 tools to chain, invoke a playbook and the agent gets an ordered, argument-correct plan. Between them they reach every tool on the server, so an agent that only reads prompts/list still finds the whole surface.
Playbook | What it does |
| Start here — catalog, corpus shape, categories, TLQL grammar |
| CVE end-to-end: severity, exploitation, exposure, remediation |
| Actor dossier: TTPs, targeting, attribution confidence |
| Indicator → linked threats, blast radius, blocking action |
| Aggregate questions in TLQL over the hunt index |
| Open-ended research via semantic corpus search |
| Map a threat's SPL/KQL/Sigma to ATT&CK, flag gaps |
| Highest-value detection debt, ranked by exposure |
| Draft a deployable rule grounded in corpus logic |
| Forecast the next (or preceding) ATT&CK techniques |
| Why two threats are linked, with the evidence |
| Campaign members, shared infra, pivotal entities |
| Audit whether an attribution is evidence-backed |
| Pivot across DNS, hosting and adjacent infrastructure |
| Profile a malware family or offensive tool |
| Firewall-ready C2 blocklist with operator clustering |
| Fold community signal in; surface coverage lead time |
| Triage by exploitability, not CVSS alone |
| Simulations paired with the detections they should trip |
| STIX 2.1, ATT&CK Navigator, SIEM-ready rules |
| Batch a list of threat/CVE ids without N round-trips |
| Covered vs uncovered for a CVE, actor or technique |
| Today's posture, top new threats, daily theme |
| Review a day or span from the debrief archive |
| Corpus health, engine state, enrichment completeness |
Full tool catalog
For the complete list of 81 tools with parameters and example invocations, see the interactive MCP documentation page.
Architecture
Transport: stdio (local subprocess)
Auth:
THREADLINQS_API_KEYenvironment variable (Bearer token to the worker API)Runtime: Node ≥18
SDK:
@modelcontextprotocol/sdk@^1.26.0Backend: Cloudflare Workers + D1 (multi-region)
Purple gate: the server checks the API key's tier at startup and warns if it is missing, invalid, or below Purple/Gold (tier ≥ 3) — it starts regardless so the tool catalog stays introspectable; the gate itself is enforced server-side on every tool call (structured 403 on lapse or under-tier)
Introspection has three tiers (since 8.1.0): authenticated
tools/list→ the public/mcp/catalog.json→ a catalog snapshot bundled in the package. The first two need network; the third does not, sotools/listreturns the real catalog even in a fully network-isolated sandbox. Previously that case returned an empty array — not an error, an empty list, which is indistinguishable from a server with no tools, and is why registry scanners indexed this server with zero tools.Maintainers: regenerate the snapshot with
npm run sync:catalogafter deploying the worker, since the worker owns the tool and prompt registries.npm run test:catalogfails the build when the snapshot and the live catalog disagree, and it runs onprepublishOnly.
Links
License
MIT © Threadlinqs
Available Tools
81 toolsbulk_get_cvesBulk Get CVEsARead-onlyIdempotent
Fetch up to 20 enriched CVEs by ID in one call. Returns {cves, missing, count}.
| Name | Required | Description | Default |
|---|---|---|---|
| cve_ids | Yes | CVE IDs (max 20) |
Output Schema
| Name | Required | Description |
|---|---|---|
| cves | Yes | |
| count | No | |
| missing | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is fully covered by structured data. The description adds the 20-item cap and the return shape {cves, missing, count}. The 'missing' field implies that some requested IDs may not be found, which is useful behavioral context the annotations don't capture.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste. The first sentence states the action and cap, the second states the return shape. Everything earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is an output schema present, so return values are documented there. The description covers the key behavioral notes (20 limit, enriched data, missing handling). For a simple 1-parameter, read-only tool with good annotations and full schema coverage, this is essentially complete. Minor gap: doesn't specify what 'enriched' means relative to the singular get_cve.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the cve_ids parameter fully ('CVE IDs (max 20)'). The description adds the return-format detail but not new parameter semantics beyond what the schema provides. Baseline 3 is appropriate since the schema carries the parameter documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Fetch up to 20 enriched CVEs by ID in one call' — a specific verb (fetch), resource (CVEs), and scoping constraint (by ID, up to 20, in one call). It distinguishes from the sibling get_cve (singular) and bulk_get_threats by specifying the resource type and batch limit. Returns structure is also noted, adding clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage — use this when you need multiple CVEs in one call rather than calling get_cve repeatedly. However, it does not explicitly state when NOT to use it or name alternatives (e.g., when you need fewer than 20, or when get_cve is preferable). The sibling differentiation is implicit via the bulk/batch framing but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bulk_get_threatsBulk Get ThreatsARead-onlyIdempotent
Fetch up to 20 threats by ID in one call. Returns LEAN rows by default (identity, severity, attribution, CVEs, targets + counts for MITRE/IOCs/detections/timeline/tags), which is what makes 20 ids actually fit in one response. count is the number of rows actually present in threats[]; unresolvable ids come back in missing. detail="full" returns whole dossiers but is capped at 3 ids per call (a full dossier is ~68 KB) — the overflow is named in deferred_ids, never silently dropped. Drill into any row with get_threat(id).
| Name | Required | Description | Default |
|---|---|---|---|
| detail | No | "summary" (default, all 20 fit) | "full" (whole dossiers, max 3 ids per call) | |
| threat_ids | Yes | Threat IDs (max 20) |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | Rows actually present in threats[] — safe to iterate on. |
| detail | No | "summary" | "full" — which row shape threats[] carries. |
| missing | Yes | |
| threats | Yes | |
| requested | No | How many ids the caller supplied. |
| detail_hint | No | |
| deferred_ids | No | |
| deferred_reason | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered; the description adds valuable behavior beyond that: lean vs full row semantics, the reason a full dossier caps at 3 (~68 KB), and the guarantee that overflow is named in `deferred_ids` and 'never silently dropped.' The `missing` behavior for unresolvable IDs is also disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: core capability first, then default-payload detail, then full mode, then cross-reference. No filler or repeated schema text; the most important constraint (20 IDs per call) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers everything an agent needs to invoke correctly and interpret the result: the batch cap, both detail modes, overflow handling, missing IDs, and a pointer to the single-ID fallback. An output schema is present for return fields, so the description's grounding from `count`/`missing`/`deferred_ids` is ample.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; both parameters are already documented, including the detail enum and max 20 on threat_ids. The description adds marginal value by explaining response-related semantics: what `count` counts, what `missing` contains, and why detail='summary' is what makes 20 fit in one response.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb, resource, and constraint: 'Fetch up to 20 threats by ID in one call.' This cleanly separates it from single-ID get_threat, search-based search_threats, and get_recent_threats without needing to read any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative tool with its use case: 'Drill into any row with get_threat(id).' It also gives conditions for choosing the detail mode ('detail="summary" default, all 20 fit' vs 'detail="full"... max 3 ids per call'), so an agent knows when and how to call rather than guessing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_correlationExplain CorrelationARead-onlyIdempotent
Why two threats are linked: the per-channel similarity decomposition (techniques, IOCs, CVEs, products, CWEs, context), which channel dominates and by how much, the concrete shared artifacts, the signal count, and quality flags for high-confidence/low-evidence and stale links. Use when get_similar_threats gives a score and you need the evidence behind it. Pass the pair in either order. Returns 404 when the engine has no edge between them.
| Name | Required | Description | Default |
|---|---|---|---|
| threat_a | Yes | First threat ID. | |
| threat_b | Yes | Second threat ID. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present with HTTP 404 when the engine has no edge between the pair. |
| is_stale | No | |
| dominance | No | |
| shared_cves | No | |
| shared_iocs | No | |
| signal_count | No | |
| score_breakdown | No | |
| shared_techniques | No | |
| is_high_conf_low_signal | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explains what the tool returns in detail (channels, dominant channel, artifacts, signal count, quality flags) beyond what output schema could convey. It also discloses the 404 behavior when no edge exists, which is useful behavioral context. The readOnlyHint=true and idempotentHint=true annotations are consistent with the description's read-operation framing, so there is no contradiction. The 404 disclosure adds genuine value not present in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with zero wasted words. Every clause carries informational weight - the return contents, the intended usage trigger, the order-independence note, and the 404 case. Front-loaded with the primary purpose, followed by usage context. This is exemplary conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema present, so return value documentation is handled there. The description covers the essential behavioral surface: what it computes, what it returns, when to use it, how parameters relate (order-independent), and the error case (404). For a relatively simple two-parameter correlation explanation tool with annotations and output schema supporting it, this description is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters are self-documenting ('First threat ID' / 'Second threat ID'). The description adds one meaningful detail beyond the schema: the pair can be passed in either order (order independence). With complete schema coverage, baseline 3 is appropriate, and the order-independence note justifies not docking further but doesn't elevate beyond 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource structure ('explain correlation') with detailed scope: the per-channel similarity decomposition, dominant channel, shared artifacts, signal count, and quality flags. It clearly distinguishes this tool from the sibling get_correlation_path, get_correlation_subgraph, and get_similar_threats by focusing on the evidence/explanation behind a similarity score rather than the path or subgraph.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('Use when get_similar_threats gives a score and you need the evidence behind it'), naming the predecessor tool by name. It also addresses invocation details ('Pass the pair in either order' - order independence) and the 404 error case when no edge exists. This is model usage guidance with explicit trigger conditions and alternative references.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_detectionExport DetectionARead-onlyIdempotent
Export one detection rule in a specific format. format=spl|kql|sigma returns the raw query text for that flavor; format=json returns the full detection object.
| Name | Required | Description | Default |
|---|---|---|---|
| format | Yes | spl, kql, sigma, or json | |
| detection_id | Yes | Detection ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| format | No | |
| content | No | Rule text for spl/kql/sigma. For format=json the detection object is returned directly instead. |
| available | No | |
| detection_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds behavioral value by clarifying what is returned per format flavor (raw query text vs. full object), which is useful beyond the annotations. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste, front-loaded with the core purpose. It's efficient and every clause earns its place. Slightly more could be added about detection_id semantics but not required.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (2 params, both required, no nested objects) and has an output schema plus strong annotations. The description explains the format value semantics adequately. Could mention what formats are unsupported or typical file extensions, but for the simplicity level this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters. The description adds the interpretation of the format values (spl/kql/sigma = raw text, json = full object), which is a genuine enhancement, though light. Baseline 3 is appropriate given high schema coverage and the modest added meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (export) with a specific resource (one detection rule) and specifies the format dimension, distinguishing it from sibling tools like get_detections and export_stix. The scope ('one detection rule') is clearly delimited against bulk-export siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly explains the format parameter semantics, distinguishing raw query text (spl/kql/sigma) from the full object (json). It doesn't explicitly name alternatives like export_stix or get_detections, but the format-flavor distinction gives strong usage context for when this vs. other export/get tools is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_stixExport STIX 2.1 BundleARead-onlyIdempotent
Export a threat, actor, or CVE as a STIX 2.1 bundle for ingestion into a TIP/SIEM. Provide at least one of threat_id, actor, or cve_id. Returns a {type:"bundle", objects:[...]} with indicator (per IOC), attack-pattern (per MITRE technique), intrusion-set (actor), vulnerability (CVE), malware/threat-actor, and relationship objects. Set include_osint=true to add sighting SROs for indicators the community independently reported (TL_OSINT_Scan / tweetfeed.live, CC0) — community-sourced and heavily concentrated, so they carry x_threadlinqs_trust="community-unverified". The bundle is capped (≤200 objects / ≤80KB); a note object is appended if truncated.
| Name | Required | Description | Default |
|---|---|---|---|
| actor | No | Threat-actor name or alias to export (e.g. "APT29") | |
| cve_id | No | CVE identifier to export (e.g. CVE-2024-3400) | |
| threat_id | No | Threat ID to export (e.g. TL-2026-0042) | |
| include_osint | No | Add community `sighting` objects for corroborated indicators (default false) |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| type | Yes | Always 'bundle'. |
| objects | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context: the 200-object/80KB cap with a note object on truncation, the trust flag 'community-unverified' for OSINT data, and the return structure with specific object types. It doesn't detail auth/permission requirements, but annotations cover the mutation-safety aspect well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, information-dense paragraph with no wasted words. Every sentence carries meaningful content: purpose, parameter requirement, output structure, OSINT option semantics, and truncation behavior. It could be slightly more structured (e.g., separating return format from option behavior), but it is appropriately compact for the richness it conveys.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and annotations are strong (readOnly, idempotent, non-destructive), the description fully covers the remaining contextual needs: return object structure, option semantics with trust implications, truncation limits, and the at-least-one-input requirement. This is complete for a moderately complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 4 parameters are documented in the schema. The description adds context that 'at least one' identifier is needed and explains the include_osint side-effect (adds sighting SROs with a community trust flag), which goes slightly beyond the schema. This is a solid baseline-plus scenario where schema handles most of the lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb+resource (export a threat/actor/CVE as STIX 2.1 bundle) and the audience purpose (ingestion into TIP/SIEM). It distinguishes from siblings like export_detection and get_threat_bundle by specifying the STIX 2.1 format and detailed object composition, which are unique.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the requirement of 'provide at least one of threat_id, actor, or cve_id' and explains the optional include_osint behavior with its caveats. However, it does not explicitly say when NOT to use this tool versus alternatives like export_detection or get_threat_bundle, though the STIX format and TIP/SIEM ingestion purpose imply differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_c2_blocklistGenerate C2 BlocklistARead-onlyIdempotent
Compile a firewall-ready C2 blocklist of active command-and-control IPs observed recently. Returns deduplicated network indicators ready to drop into a denylist. Use this for actionable blocking; use get_c2 with view="beacons" when you need the underlying beacon detail.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| cidrs | No | |
| count | Yes | |
| detail | No | |
| since_days | No | |
| generated_at | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the agent knows this is a safe, non-mutating operation. The description adds useful context about the output being deduplicated network indicators and firewall-ready format, but doesn't disclose additional behavioral traits beyond that (e.g., recency window, format specifics, or staleness policy). With annotations covering the safety profile, adding the dedup/actionable context earns a moderate score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose, and the second sentence provides the alternative-tool guidance. Every clause earns its place with zero filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no parameters, an output schema exists, and annotations fully declare the behavioral safety profile. The description covers purpose, output format, and alternative tool selection. The only minor gap is not clarifying the exact recency window or time range of 'recently observed' indicators, but with an output schema present, the return format doesn't need description. This is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and 100% schema description coverage is trivially satisfied. The description does not need to explain parameters because there are none. A baseline of 4 is appropriate for a zero-parameter tool where there is nothing to document.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool does: compiles a firewall-ready C2 blocklist of active IPs, returns deduplicated indicators ready for a denylist. It distinguishes itself from sibling get_c2 by specifying when to use each ('use get_c2 with view="beacons" when you need the underlying beacon detail'). Specific verb (compile/generate) + specific resource (C2 blocklist) makes the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('Use this for actionable blocking') and names the alternative (get_c2 with view='beacons') for when beacon detail is needed. This is an explicit when/when-not pairing with a sibling named directly, satisfying the highest bar for usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_actorGet Actor ProfileARead-onlyIdempotent
Get a lean threat-actor profile by name or alias: actor metadata, attribution counts, attributed-threat summary rows, MITRE tactic rollup + technique ids, IOC category counts (no raw values), CVE/CWE/tool summaries, and relationships. Tactic keys are canonicalised (the corpus writes both "Credential Access" and "credential-access") and the rollup counts DISTINCT TECHNIQUES per tactic; mitre.technique_ids is capped at 60 against mitre.techniques_total. relationships splits into shared_infra / shared_techniques / shared_tooling with the type re-derived from the value, because corr_attribution types tool names as hashes. An empty actor_relationships means UNRECORDED, not unrelated — see actor_relationships_coverage. For heavy detail use the follow-up tools: get_threat(id) for a full threat, search_detections / get_detection_detail for detection bodies, search_iocs for IOC values, get_infrastructure_pivots for shared infrastructure.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Actor name or alias (e.g. 'APT29', 'Lazarus Group') |
Output Schema
| Name | Required | Description |
|---|---|---|
| cves | No | |
| actor | Yes | |
| mitre | No | |
| tools | No | |
| counts | No | |
| targets | No | |
| threats | No | |
| relationships | No | |
| actor_relationships | No | |
| actor_relationships_coverage | No | Present only when actor_relationships is empty: says the baseline has no row, not that the actor is unrelated. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive behavior. The description goes well beyond that by disclosing canonicalisation of tactic keys, DISTINCT technique counting, the 60-cap on mitre.technique_ids, relationship re-derivation, and the meaning of empty relationship lists. These are non-obvious behaviors an agent needs to understand the output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though long, every clause carries semantic weight: the output inventory is compact, edge-case behavior is stated directly, and follow-up routing is front-loaded. The long sentence is dense but not bloated, and important caveats are placed ahead of alternatives.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the description need not re-specify return shapes. It covers the response's semantics, known data-quality quirks, the coverage caveat for relationships, and alternative tools for heavier detail. Nothing needed to invoke or interpret this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already documents name as 'Actor name or alias (e.g. 'APT29', 'Lazarus Group')'. The description's 'by name or alias' repeats rather than extends this. No additional parameter-level semantics are contributed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get a lean threat-actor profile by name or alias.' It enumerates the exact contents (metadata, attribution counts, MITRE rollups, IOC category counts, summaries, relationships), which clearly distinguishes it from siblings like get_actor_intelligence and get_threat.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'For heavy detail use the follow-up tools' and names get_threat, search_detections, get_detection_detail, search_iocs, and get_infrastructure_pivots. It also warns that an empty actor_relationships means 'UNRECORDED' rather than 'unrelated,' giving the agent interpretative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_actor_intelligenceActor IntelligenceARead-onlyIdempotent
Composite intelligence picture for a threat actor: the actor profile (threats, MITRE, IOC counts, CVEs, tooling, targets), the known actor_relationships baseline, plus cross-actor attribution SCOPED TO THIS ACTOR — only shared entities whose actor list names it or one of its aliases, ranked by attribution belief (shared malware/infrastructure outranks commodity TTPs). Use it to answer "who else does this actor overlap with, and on what evidence".
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Threat-actor name or alias (e.g. "APT29") |
Output Schema
| Name | Required | Description |
|---|---|---|
| cves | No | |
| actor | No | |
| mitre | No | |
| tools | No | |
| threats | No | |
| actor_relationships | No | |
| cross_actor_attribution | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent hints, the description discloses exactly how attribution is filtered and ranked: only shared entities whose actor list includes this actor or its aliases, with shared malware/infrastructure ranked above commodity TTPs. This adds meaningful behavioral context that annotations do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences carry the full message: the core purpose is front-loaded, followed by scope and ranking details. It is somewhat dense with parentheticals and capitalized emphasis, but every phrase adds value without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return details need not be described. A single required parameter is fully documented in the schema, and the description covers filtering, ranking, and intended use, making the tool callable without ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully covers the single 'name' parameter with its type and example. The description does not add parameter-level detail, but with 100% schema coverage, the baseline applies without requiring compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific composite intelligence picture for a threat actor with an enumerated scope: profile, actor_relationships baseline, and cross-actor attribution. It distinguishes itself from simpler siblings like get_actor or get_actor_relationships by emphasizing the cross-actor attribution component.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly frames the use case: "Use it to answer 'who else does this actor overlap with, and on what evidence'." It also explains scope boundaries, but does not name alternative tools or provide when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_actor_relationshipsKnown Actor LinksARead-onlyIdempotent
The platform's baseline of ALREADY-DOCUMENTED links between threat actors (subgroup / overlaps / similar / linked-to) with both uuids and the source. Call this before claiming any actor-to-actor relationship is new — it is the only surface that says whether a link is public knowledge. CRITICAL: this table is sparse, covering a small minority of the corpus's actor labels (the response carries live coverage numbers). An empty result means the link is UNRECORDED, never that it was disproved or that the actors are unrelated. Use it to rule a claim out of NOVELTY, never to rule a relationship out of EXISTENCE. Matches both slots, so it also returns rows where your actor is the target — get_actor's relationship list does not.
| Name | Required | Description | Default |
|---|---|---|---|
| actor | No | Optional: only rows naming this actor on either side (e.g. "Lazarus Group"). Omit to list the whole baseline. | |
| limit | No | Default 50, max 200. | |
| rel_type | No | Optional: filter by relationship type. The response's coverage.rel_types lists what is actually present. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| caveat | Yes | Absence-is-not-evidence statement. Do not drop it when summarising. |
| coverage | Yes | |
| unrecorded | No | Present and true when an `actor` filter matched nothing. Means UNRECORDED, not "no relationships exist". |
| unrecorded_note | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint, idempotentHint, and destructiveHint annotations, the description discloses that the table is sparse, that empty results mean 'unrecorded' rather than 'disproved', and that live coverage numbers are included in the response. This semantic nuance is essential for avoiding false negative conclusions and is not available from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and each sentence carries distinct value: scope, novelty semantics, exclusion semantics, sparsity warning, and parameter behavior. It is longer than an average description but every sentence earns its place, and the CRITICAL flag correctly draws attention to the most important interpretive rule.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully contextualizes this tool: it tells the agent why it exists, what it cannot prove, what emptiness means, how it differs from an alternative, and what live coverage info will accompany the response. Combined with an output schema, nothing needed for correct invocation or interpretation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters are already documented, but the description adds operational meaning: actor applies to either side, 'Omit to list the whole baseline', and rel_type results can be discovered through the response's coverage.rel_types field. This goes beyond the schema's structural descriptions without being redundant.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (already-documented actor-to-actor links) with a specific verb (get) and explicitly lists relationship types like subgroup/overlaps/similar/linked-to. It also distinguishes itself from get_actor's relationship list by noting it matches both actor slots, so an agent can tell this tool apart from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to call it ('Call this before claiming any actor-to-actor relationship is new') and what not to infer from it ('never to rule a relationship out of EXISTENCE'). It even names the alternative behavior in get_actor that differs, giving the agent clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_atlas_intelligenceATLAS (Adversarial ML)ARead-onlyIdempotent
MITRE ATLAS technique co-occurrence for threats that attack AI/ML systems — prompt injection, agent-tool abuse, context and memory poisoning, cost harvesting. data returns pairs whose BOTH endpoints are real ATLAS ids (^AML.), with cooccurrence_count, support, confidence and lift; free-text publish labels ("Prompt Injection", "Tool Poisoning") are returned SEPARATELY in tag_pairs and are not ATLAS techniques. SMALL-N WARNING: the corpus holds 106 pairs of which only 10 were observed more than once, so min_cooccurrence defaults to 2. Lower it and you get rows where confidence=1.0 and lift=1/support are arithmetic on a single observation — those carry single_observation:true; do not report them as associations. Ranked by cooccurrence_count, then lift.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max pairs per list (default 50, max 100) | |
| min_cooccurrence | No | Minimum times the two techniques were seen together. Default 2 (the honest set). 1 includes single-observation pairs, which are flagged single_observation:true. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| note | No | |
| count | No | |
| pairs | No | |
| corpus | No | |
| filters | No | |
| tag_pairs | No | |
| tag_pair_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only and idempotent, and the description adds substantial behavioral context: the distinction between data and tag_pairs, the field names and ranking order, the single_observation:true flag, and the data-quality caveat about 106 total pairs. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence provides operational value: scope, data field meaning, ranking, the small-n warning, and threshold semantics. It is structured logically and front-loaded with the core resource and purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with only two parameters and an output schema, this description is unusually complete. It covers the data-quality caveats, field semantics, ordering, and interpretation warnings that an agent needs to correctly use the results. Nothing functionally important is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes both parameters at 100% coverage, but the description adds important semantics for min_cooccurrence: default 2 means the honest set, setting 1 includes single-observation pairs, and those rows should not be treated as true associations. This extra meaning goes beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('returns pairs'), a specific resource (MITRE ATLAS technique co-occurrence), and the scope (threats that attack AI/ML systems). It also explicitly distinguishes ATLAS techniques from free-text publish tags, so an agent can tell it apart from general MITRE or threat-search siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear on how to interpret results, especially the small-n warning: it tells agents not to report single-observation pairs as associations and that min_cooccurrence=2 is the honest default. It provides clear dataset context, though it doesn't explicitly name alternative sibling tools or when to use them instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_attack_flowAttack FlowARead-onlyIdempotent
Get the analyst-authored MITRE ATT&CK Flow for a threat: a causal DAG of actions, conditions, operators and assets, with per-node technique ids, tactics and descriptions. This is asserted causality — what actually caused what — not a flat technique list. Check generator: 'harness' is authored, 'derived' is timeline ORDERING and must not be read as causality. Use get_flow_similar_threats to find threats sharing a causal sequence.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | 'ir' (default) returns the compact flow IR plus validation findings; 'nodes' returns the denormalized node/edge/asset projection with technique and tactic columns already joined. | |
| threat_id | Yes | Threat ID (e.g. TL-2026-1916) |
Output Schema
| Name | Required | Description |
|---|---|---|
| flow | No | |
| generator | No | 'harness' = analyst-authored causality. 'derived' = timeline ORDERING only — must not be read as causality. 'unknown' = published before provenance was tracked; treat as not authoritative. |
| threat_id | Yes | |
| flow_valid | No | |
| node_count | No | |
| flow_errors | No | |
| flow_warnings | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior, so the description adds more useful behavioral context. It explains how to interpret the 'generator' field and asserts that 'derived' ordering must not be read as causality, which is valuable beyond what annotations or schema provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three focused sentences, each carrying necessary information: what the tool returns, an important causal interpretation caveat, and an alternative tool for similar causal sequences. No filler is present, and the most relevant definitions come first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich annotations, full parameter coverage, an output schema, and a detailed semantics explanation, the description fully equips an agent to understand what the tool returns and how to interpret it. The alternate tool reference adds extra context for when this tool is the wrong choice.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters and their differences are already well documented. The description does not add much parameter-level detail, but it does clarify the semantic meaning of the returned data. With a high-coverage schema, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('get the analyst-authored MITRE ATT&CK Flow for a threat') and defines the result as a causal DAG of actions, conditions, operators, and assets. It explicitly contrasts itself with a flat technique list, which makes its purpose clear and distinguishes it from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage guidance by stating the tool returns asserted causality rather than a flat technique list, and warns against misreading 'derived' timelines as causal. It also names get_flow_similar_threats as the alternative for finding threats sharing a causal sequence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_attribution_coverageAttribution CoverageARead-onlyIdempotent
Corpus-level attribution honesty: how many threats are genuinely assessed vs merely actor-labelled at ingest vs uncovered, broken down by confidence, scope and reason code, plus the research backlog, contradictions, top actors and the research clock (last real assessment, not last nightly intake).
| Name | Required | Description | Default |
|---|---|---|---|
| actor | No | Optional — scope the `recent` list to one actor. |
Output Schema
| Name | Required | Description |
|---|---|---|
| corpus | No | |
| engine | No | |
| recent | No | |
| by_scope | No | |
| by_reason | No | |
| top_actors | No | |
| by_confidence | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a safe, idempotent read operation. The description adds behavioral nuance by distinguishing 'last real assessment' from 'last nightly intake,' and revealing it exposes research backlog/contradictions. This goes beyond basic read-only semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense sentence covering many output components. It is compact but somewhat run-on; it could be front-loaded and broken into clearer phrases. Still, no waste words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the key data dimensions (breakdowns, backlog, contradictions, top actors, research clock) and annotations/output schema handle safety and return format. Missing is any explanation of the optional actor parameter or the 'recent' list it scopes, which is a gap relative to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema fully documents the one optional parameter (actor) with a clear description, so baseline is 3. However, the tool description never mentions the 'recent' list that the parameter refers to, creating a slight disconnect between the description's corpus-level scope and the parameter's scoping behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly defines the tool as providing corpus-level attribution coverage metrics, distinguishing between genuinely assessed, actor-labelled, and uncovered threats. This differentiates it from sibling tools like get_attribution_evidence, which focuses on evidence for a specific entity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for understanding overall attribution quality but does not state when to use it versus alternative tools or explicitly mention the optional actor filter. No exclusion criteria or alternative tool names are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_attribution_evidenceAttribution EvidenceARead-onlyIdempotent
Why a threat is attributed to an actor: the verdict, canonical actor, confidence, scope, the cited evidence chain, which signals fired, suspected alternatives and the analyst reasoning. Crucially it also reports state — whether this is a researched assessment or an unresearched intake stub — which threats.threat_actor alone cannot tell you.
| Name | Required | Description | Default |
|---|---|---|---|
| threat_id | Yes | Threat ID (e.g. TL-2026-0989). |
Output Schema
| Name | Required | Description |
|---|---|---|
| actor | No | |
| scope | No | |
| state | Yes | 'assessed' vs 'pending_research' — whether this is a real assessment or an unresearched intake stub. Do not present a stub as an assessment. |
| title | No | |
| method | No | |
| signals | No | |
| verdict | No | |
| evidence | No | |
| queued_at | No | |
| reasoning | No | |
| suspected | No | |
| threat_id | Yes | |
| actor_uuid | No | |
| confidence | No | |
| reason_code | No | |
| attributed_at | No | |
| current_actor | No | |
| actor_canonical | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, which broadly cover the safety profile. The description adds meaningful value beyond annotations by disclosing the distinct `state` field semantics and the fact that this tool reveals attribution depth (researched vs intake stub) — genuinely useful behavioral context about what the returned data represents.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste. The first sentence enumerates the data fields returned; the second delivers the crucial differentiator (`state` and what it means). Every clause earns its place, and the example format mention adds concrete value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a single required parameter, a high-coverage schema, full annotations, and an output schema present, most of the burden is already handled structurally. The description covers the key addition (state field semantics). It's a complete description for a focused, single-parameter lookup tool, though it could mention the output format/pagination slightly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description clearly explains what the returned data will contain, which helps the agent understand what it's getting. The single parameter threat_id is fully documented in the schema with an example. With full schema coverage and one simple parameter, the description adds no additional parameter semantics needed beyond what's already provided, warranting the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states this tool returns the attribution evidence for a threat: verdict, canonical actor, confidence, scope, evidence chain, signals, alternatives, and analyst reasoning. It explicitly distinguishes its purpose from siblings like get_threat by highlighting that it reports `state` (researched vs unresearched intake stub) which threats.threat_actor alone cannot convey.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains that this tool reveals whether an attribution is a researched assessment or an unresearched stub — useful context for when to trust the output. However, it doesn't explicitly name when-not-to-use or point to alternative tools for getting the threat actor, leaving the when/alternative guidance implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_c2C2 IntelligenceARead-onlyIdempotent
Query the live C2 (command-and-control) intelligence center. Pick a view: 'beacons' (active C2 beacon snapshots — default), 'configs' (full extracted C2 configs), 'operators' (operator clusters), 'watermarks' (Cobalt Strike watermark index), 'correlations' (cross-C2 correlations), 'timeline' (activity over time), 'stats' (aggregate counts). Use generate_c2_blocklist when you want firewall-ready output rather than raw records.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | Which C2 dataset to return (default 'beacons') | |
| limit | No | Max records for the record-bearing views — beacons (default 50), configs (default 25), correlations (default 25). Max 100. | |
| offset | No | Skip this many records — 'correlations' only; the aggregate summary block stays whole across pages. |
Output Schema
| Name | Required | Description |
|---|---|---|
| asns | No | |
| data | No | |
| items | No | |
| total | No | |
| months | No | |
| beacons | No | |
| configs | No | |
| clusters | No | |
| versions | No | |
| countries | No | |
| aggregates | No | |
| watermarks | No | |
| correlations | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context beyond that: it positions the data as 'live', names the default view as 'beacons', and clarifies that the tool returns raw records rather than transformed blocklist output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact: one sentence states the main purpose, one enumerates the views with useful semantics, and one names the alternative tool. Every section earns its place and the most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 100% schema coverage, an output schema, and robust annotations, the description only needed to add purpose, view semantics, and sibling differentiation — all of which it provides. The missing details such as exact default limits and the offset caveat are present in the input schema, so nothing essential is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline starts at 3. The description goes beyond the schema by clarifying what each view means — for example, 'watermarks' is a Cobalt Strike watermark index and 'correlations' contains cross-C2 correlations — which makes the enum values more interpretable for an agent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as querying the live C2 intelligence center and enumerates seven concrete views with short parenthetical definitions. It also distinguishes itself from the sibling generate_c2_blocklist by contrasting raw records with firewall-ready output, so an agent can pick the right tool without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains the available data views and names the alternative generate_c2_blocklist for firewall-ready output. This gives the agent concrete when-to-use and when-not-to-use guidance rather than leaving that to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_c2_dns_intelC2 DNS UnmaskingARead-onlyIdempotent
Reverse-DNS unmasking of C2 beacon infrastructure: which domains ride on each beacon IP, infrastructure fidelity (dedicated / mixed / shared), compromised-host flags and sample domains. Answers "what else lives on this C2 infrastructure". Filter by fidelity to separate adversary-owned infrastructure from shared hosting.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 40, max 100. | |
| fidelity | No | ||
| compromised | No | Only hosts flagged as compromised rather than adversary-owned. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | |
| stats | No | |
| total | No | |
| offset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds meaningful behavioral context by explaining the output categories (dedicated/mixed/shared fidelity, compromised flags) and the underlying reverse-DNS approach. It does not contradict any annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with the core purpose. The second sentence adds actionable guidance on filtering. No filler or redundant detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering safety, the description fully explains the tool's purpose, key filters, and output nature. It does not address pagination or edge cases, but these are not critical for a read-only get tool with schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers limit and compromised descriptions; description reinforces fidelity filtering and compromised-host flags, giving tactical meaning beyond the enum. Limit's default/max is already in the schema, so no duplication needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource: 'Reverse-DNS unmasking of C2 beacon infrastructure' and explicitly states what it returns (domains per IP, fidelity, compromised-host flags). It clearly distinguishes this from sibling tools like get_c2 or get_ioc_dns by focusing on infrastructure fidelity and shared-hosting separation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context: 'Answers "what else lives on this C2 infrastructure"' and instructs to 'Filter by fidelity to separate adversary-owned infrastructure from shared hosting.' It does not explicitly name alternative tools, but the guidance is sufficient for choosing this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_campaign_intelligenceCampaign IntelligenceARead-onlyIdempotent
Pivot on a named campaign / operation by name (e.g. "Snowflake campaign", "ClickFix"). Returns the threats in the campaign, the actors involved, prevalence, and common ATT&CK techniques. Membership is the UNION of the curated threat_campaign_refs table and threats whose own TITLE names the campaign, because the curated table is thin (ClickFix: 7 curated rows against 57 threats that name it). Each threat carries matched_via (grounded | title | grounded+title) and the response carries a membership breakdown — neither source is complete, so treat title rows as leads and check them before calling them members.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Campaign / operation name |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | No | |
| actors | No | |
| matched | Yes | |
| threats | No | |
| canonical | No | |
| membership | No | |
| prevalence | No | |
| entity_type | No | |
| top_techniques | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond annotations by explaining how membership is computed (the lightweight UNION of curated references and threats matching by title), warns that the curated table is thin, names the `matched_via` field values, and tells the agent to treat title-matched rows as leads. This is excellent behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence serves a purpose: core action, output contents, membership source, and important caveat about trustworthiness. The warning about title rows is essential and the ClickFix example justifies why the union is needed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A given output schema handles return shape, and the description fully covers what the tool does, how membership is sourced, and how to treat results. Nothing important needed by an agent deciding to call or trust it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the schema already documents the name parameter. The description adds extra value through concrete examples like 'Snowflake campaign' and 'ClickFix' and clarifies that title-based matching also matters, helping the agent pick a good input.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Pivot on a named campaign / operation by name'. It lists concrete returns — threats, actors, prevalence, ATT&CK techniques — so an agent knows exactly what intelligence it will get for a named campaign.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is clear: call this when you have a campaign name like 'Snowflake campaign' or 'ClickFix'. There is no explicit mention of when not to use it or comparison to sibling tools like list_campaigns or search_threats, so it does not reach 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_changelogGet ChangelogARead-onlyIdempotent
Get the platform changelog (new threats, detections, features), strictly newest-first by date. Pass limit (default 20, max 100). NOTE: this is a hand-maintained release feed, not a deploy log — it stopped being written in Feb 2026, so the response carries latest_entry_date / stale_days / a warning. For what the platform actually looks like NOW use get_platform_stats (live corpus counts) and get_engine_status (pipeline state); do not answer "what changed recently" from this alone.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max entries (default 20, max 100) |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| stale | No | |
| total | No | |
| entries | Yes | |
| warning | No | Present when the feed is stale; says what it does NOT cover. |
| has_more | No | |
| stale_days | No | |
| latest_entry_date | No | Date of the newest entry — the feed cut-off. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that this is a hand-maintained release feed, not a deploy log, that it stopped being written in Feb 2026, and that the response carries latest_entry_date, stale_days, and a warning. This is valuable behavioral context well beyond what the idempotent/read-only annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the resource and ordering constraint, the parameter guidance, and the critical staleness warning with alternatives. The most decision-relevant caveat is front-loaded and clearly formatted with NOTE.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read tool with an output schema, the description is fully sufficient: it explains the data source, staleness, expected response markers, and directs the agent to the correct sibling tools. Nothing needed for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents limit with default and max values, and schema description coverage is 100%. The description restates 'Pass limit (default 20, max 100)' but adds no new semantic meaning beyond reinforcing that the parameter is optional.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states this tool returns the platform changelog — new threats, detections, and features — ordered strictly newest-first by date. It goes beyond a mere restatement of the name by specifying the content scope and ordering behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to avoid relying on this tool: for current platform state, use get_platform_stats or get_engine_status instead. It also warns not to answer 'what changed recently' from this feed alone, giving clear routing guidance relative to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_community_campaignsCommunity CampaignsARead-onlyIdempotent
Campaign clusters from the community OSINT layer (tweetfeed.live, CC0): cluster name, confidence, targeted brand, first/last seen, indicator count and types, tags and reporters. Cluster labels are UPSTREAM AI output, not Threadlinqs attribution — do not present them as our assessment. On an upstream proxy failure the response carries community_error rather than erroring; report "community feed unavailable", not "no campaigns".
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 15, max 50. |
Output Schema
| Name | Required | Description |
|---|---|---|
| window | No | |
| campaigns | No | |
| generated_at | No | |
| community_error | No | Set to 'upstream_unavailable' on a proxy failure — report the feed as unavailable, NOT as zero campaigns. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds meaningful behavioral details beyond annotations: upstream proxy failure returns community_error instead of erroring, and cluster labels are upstream AI output rather than Threadlinqs attribution. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no redundant content. Each sentence earns its place: first lists the contents, second clarifies data provenance, third explains error handling. Very concise and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values are documented. The description covers purpose, data source, content fields, provenance caveat, and error behavior. Only missing explicit alternative tool comparisons, which for a simple read-only list tool is an acceptable gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 100% coverage for the single parameter 'limit' with its description (default 15, max 50). The tool description adds no further information about parameter usage, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly identifies what is returned (campaign clusters from community OSINT layer) and lists specific fields (cluster name, confidence, targeted brand, first/last seen, indicator count/types, tags, reporters). It distinguishes from siblings by naming the source (tweetfeed.live, CC0) and explicitly stating that cluster labels are upstream AI output, not Threadlinqs attribution.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied usage context is strong: the tool provides community-layer campaign data, and the description gives guidance on how to interpret labels (do not present as our assessment) and how to handle errors (report 'community feed unavailable' rather than 'no campaigns'). However, no explicit alternative tools or when-not-to-use scenarios are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_correlation_pathCorrelation PathARead-onlyIdempotent
Shortest evidence path between two threats across the similarity graph: the intermediate threats, each hop's dominant linking signal and shared artifacts, and the weakest-link strength of the whole path. Answers "is this incident connected to that campaign, and through what". Returns found:false with a reason (no edges vs different components) rather than an empty array.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Target threat ID. | |
| from | Yes | Starting threat ID. | |
| max_hops | No | Search depth, 1-8 (default 6). |
Output Schema
| Name | Required | Description |
|---|---|---|
| to | Yes | |
| from | Yes | |
| hops | No | |
| found | Yes | |
| reason | No | Why no path exists (no similarity edges vs different components) when found is false. |
| path_strength | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds meaningful behavior: it explicitly discloses the found:false return shape with the reason distinction (no edges vs different components) rather than an empty array, which is valuable behavioral context beyond annotations. Missing some context like hop semantics or path weighting, but no contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler. The first sentence delivers the core value in one flowing clause, and the second sentence proactively handles the negative-return case. Every clause adds information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return values are documented separately. Both parameters are documented, annotations cover the safety profile, and the description handles the edge case (found:false) and the interpretation guidance (weakest-link strength, connectedness question). This is complete for a read-only graph-query tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear descriptions for to, from, and max_hops (including the 1-8 range and default 6). The description reinforces path semantics (hop count, weakest-link strength) that map to max_hops usage. It adds value by explaining what the path represents per hop, but relies largely on the schema which already documents all three parameters well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb-plus-resource ('Shortest evidence path between two threats across the similarity graph'), specific scope, and explicit answer to the analytical question ('is this incident connected to that campaign, and through what'). The output content is enumerated (intermediate threats, per-hop signal, weakest-link strength), which thoroughly distinguishes this from siblings like get_similar_threats or explain_correlation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool answers connectivity questions between two threats but does not explicitly say when to prefer it over explain_correlation or get_correlation_subgraph, which appear as siblings and sound adjacent in purpose. No explicit when-not/alternative guidance, though the purpose statement ('Answers is this incident connected to that campaign') provides reasonable implied context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_correlationsCorrelation EngineARead-onlyIdempotent
Read precomputed cross-dataset correlations. Choose an engine: 'overview' (rollup of all engines — default), 'mitre-heatmap', 'adversary-infra', 'ioc-consensus', 'cve-velocity', 'attribution', 'detection-debt', or 'enrichment'. Use 'overview' first to see what's available, then drill into a specific engine.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Paged engines only ('mitre-heatmap', 'ioc-consensus', 'detection-debt'): max rows, pre-ordered by score (default 50; max 200 for mitre-heatmap, 500 for the others). The summary block always covers the full set. | |
| engine | No | Which correlation engine to read (default 'overview') | |
| offset | No | Paged engines only: skip this many rows. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cves | No | |
| iocs | No | |
| engines | No | |
| sources | No | |
| summary | No | |
| sync_log | No | |
| techniques | No | |
| infrastructure | No | |
| shared_entities | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and non-destructive behavior, so the safety profile is clear. The description adds that the data is 'precomputed' and that 'overview' is a rollup across engines, which is useful behavioral context beyond annotations. It doesn't describe the response envelope, but an output schema exists and the parameter schema covers summary/paging behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences. The core purpose ('Read precomputed cross-dataset correlations') is front-loaded, followed by the engine list and the drill-down workflow. No filler or repetition of structural data.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter read tool with full schema coverage and an output schema, the description supplies the missing conceptual layer: what the engines are and the recommended access pattern. It feels complete enough for correct invocation, only lacking any comparative positioning against sibling correlation tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: all three parameters (limit, engine, offset) have detailed descriptions including enums and paging notes. The description adds strategy ('use overview first') but not parameter meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a clear verb ('Read') and a clear resource ('precomputed cross-dataset correlations'), and enumerates all engine choices. It does not explicitly contrast itself with the many correlation-related siblings like get_correlation_path or explain_correlation, so it stops short of a full sibling-differentiation 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete guidance: use 'overview' first, then drill into a specific engine. This is useful, explicit, intra-tool routing. However, it does not tell an agent when to choose this tool over the many sibling correlation tools, so it misses exclusion/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_correlation_subgraphCorrelation SubgraphARead-onlyIdempotent
The N-hop neighbourhood around any graph node — nodes, edges, and each edge's fidelity — for incremental exploration of the correlation graph. Start at depth 1 and expand: a whole-corpus graph exceeds every response budget. For a pre-aggregated single-entity view prefer get_entity_profile, which is cheaper and usually what you want; use this when you need the actual edge topology. Edges of the NPMI types (actor_technique, technique_cooccurrence) also carry the raw pmi, co_occurrence_count and the marginals {c, df_actor, df_tech, N} the score was computed from — use those, not the rounded fidelity, to compare two edges.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Hops, 1-3 (default 1). Each hop multiplies the node count. | |
| seed_id | Yes | The entity id/value to expand from. | |
| edge_type | No | Keep only edges of this type (also prunes the traversal, so it changes which nodes are reachable). Omit for all types. | |
| seed_type | Yes | ||
| limit_edges | No | Default 80, max 120 over MCP. | |
| limit_nodes | No | Default 40, max 60 over MCP. | |
| min_fidelity | No | Drop edges below this fidelity. Scale is 0-100, NOT 0-1 — typical NPMI edges sit between 5 and 30, so 0.5 filters nothing. |
Output Schema
| Name | Required | Description |
|---|---|---|
| seed | No | |
| edges | No | |
| nodes | No | |
| counts | No | |
| truncated | No | |
| params_echo | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (read-only, idempotent, non-destructive), the description discloses important behavioral details: depth expansion is resource-bounded, edge_type pruning changes which nodes are reachable, and min_fidelity uses a scale that '0.5 filters nothing.' It also warns about comparing rounded fidelity and points to raw values, all of which is practical operational behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the main purpose, followed by usage guidance and a nuanced numeric validation note. Every sentence earns its place: purpose, budget/expansion rationale, sibling differentiation, and edge-fidelity warning,
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is thorough for a graph traversal tool: it covers output shape, expansion pattern, borrowing limits, sibling selection, scale calibration, and edge-specific raw data. With an output schema present and annotations covering safety, it doesn't need to enumerate every return field. It might not describe all edge response capabilities, but nothing essential for invocation is missing enough for a 3.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high (86%), so the baseline is decent. The description adds valuable semantics beyond the schema, especially for min_fidelity ('Scale is 0-100, NOT 0-1—typical NPMI edges sit between 5 and 30') and for edge_type pruning semantics. It doesn't add elaborate semantics for every parameter, but the ones it covers are materially helpful.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description says specifically what the tool does: 'The N-hop neighbourhood around any graph node — nodes, edges, and each edge's fidelity — for incremental exploration of the correlation graph.' This clearly identifies the verb, resource, and output, and it differentiates from get_entity_profile by emphasizing 'actual edge topology.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description is explicit about when to use this tool: 'Start at depth 1 and expand' is directly tied to 'a whole-corpus graph exceeds every response budget.' It then names an alternative ('prefer get_entity_profile, which is cheaper') and the condition under which this one should be selected ('when you need the actual edge topology').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_cveGet CVEARead-onlyIdempotent
Look up a CVE by identifier (e.g. CVE-2024-3400): description, CVSS v2/v3/v4, EPSS, CISA KEV status, exploitation flags (PoC/exploit/nuclei), weaknesses (CWE ids), affected products, references, and linked threats. threat_ids is the LIVE join over threats.cve_list (threat_ids_source says so; threat_ids_note appears when the stale derived index disagreed, and any ids only that index held are surfaced separately in threat_ids_derived_only rather than merged) — it is the same linkage get_cve_intelligence reports. Enumerated pre-release CPEs are collapsed into ranges (affected_products_raw_count gives the uncollapsed count). enrichment_status distinguishes a fully enriched record from one merely seeded from KEV, where blank CVSS/EPSS means NOT MEASURED rather than measured-absent. For linked threats WITH titles/actors/detections/velocity in one call, prefer get_cve_intelligence.
| Name | Required | Description | Default |
|---|---|---|---|
| cve_id | Yes | CVE identifier (e.g. CVE-2024-3400) |
Output Schema
| Name | Required | Description |
|---|---|---|
| kev | No | |
| epss | No | |
| cve_id | Yes | |
| cvss_v3 | No | |
| enriched | No | False when the CVE is unknown — then only cve_id/valid/reason are present. |
| threat_ids | No | |
| weaknesses | No | |
| description | No | |
| exploitation | No | |
| threat_count | No | |
| published_date | No | |
| enrichment_note | No | Present only on 'not_enriched'; names the seeding source. |
| threat_ids_note | No | Present only when the derived cve_details.threat_ids reverse index disagreed with the live join. |
| affected_products | No | |
| enrichment_status | No | 'enriched' or 'not_enriched'. On 'not_enriched' a blank CVSS/EPSS/age_days means NOT MEASURED, not measured-empty. |
| threat_ids_source | No | Always 'threats.cve_list (authoritative live join)' when the join ran. |
| threat_ids_derived_only | No | |
| affected_products_raw_count | No | Entries before pre-release CPE collapsing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the readOnlyHint/idempotentHint annotations by explaining subtle behaviors: the threat_ids field is a live join from threats.cve_list, stale derived-index disagreement is surfaced via threat_ids_note and threat_ids_derived_only, pre-release CPEs are collapsed into ranges, and blank CVSS/EPSS values mean NOT MEASURED. This is exactly the kind of behavioral context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but each sentence earns its place by adding non-obvious operational details (live join, derived-only fallback, CPE collapsing, enrichment_status semantics, sibling routing). The core lookup purpose is front-loaded. It is somewhat long, but the complexity of the behavior justifies the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a small, single-parameter tool, this description covers all needed non-obvious context. The output schema can document the return structure, so the description correctly focuses on semantics that would otherwise be a surprise: linkage provenance, stale index handling, collapsed counts, and the meaning of absent metrics. Nothing critical appears missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents cve_id with an example (CVE-2024-3400), and schema description coverage is 100%. The description repeats the same parameter guidance without adding new syntax, formatting, or validation details, so it provides no extra meaning beyond the schema. A baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: looking up a CVE by identifier and enumerating the specific data returned (description, CVSS, EPSS, KEV, weaknesses, products, references, threats). It also distinguishes itself from get_cve_intelligence by noting when that richer tool is preferred.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit routing recommendation: prefer get_cve_intelligence when linked threats need titles, actors, detections, or velocity in one call. It also explains important interpretation context for enrichment_status and collapsed CPEs. It does not mention other sibling alternatives like bulk_get_cves, but for a single-CVE lookup the guidance is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_cve_intelligenceCVE IntelligenceARead-onlyIdempotent
Composite CVE dossier in one call: the enriched CVE detail, the threats that reference it (authoritative join — cve.threat_ids is reconciled to it), the attributed actors and MITRE techniques behind those threats, weaponization velocity for THIS CVE with its rank against the corpus, CWE-sibling related CVEs, and detections that name it.
| Name | Required | Description | Default |
|---|---|---|---|
| cve_id | Yes | CVE identifier (e.g. CVE-2024-3400) |
Output Schema
| Name | Required | Description |
|---|---|---|
| cve | No | |
| mitre | No | |
| actors | No | |
| threats | No | |
| related_cves | No | |
| velocity_data | No | |
| related_detections | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description adds valuable behavioral nuance: it explains the authoritative join on cve.threat_ids, the reconciliation of attributed actors and techniques, and the corpus-relative weaponization rank. This clearly matches the non-destructive read annotation with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the high-level concept 'Composite CVE dossier in one call' and then enumerates the contained components. It is dense and somewhat list-like, but every component listed contributes to understanding what the tool provides.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one required parameter, an output schema, and read-only/idempotent annotations, the description is complete. It clearly communicates the full scope of the returned intelligence including threats, actors, techniques, velocity ranking, sibling CVEs, and detections, so an agent is well-equipped to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents the single cve_id parameter with an example, so schema coverage is 100%. The description adds no additional parameter-level meaning, making the schema-based baseline of 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Composite CVE dossier in one call' with a detailed inventory of what it returns. This clearly distinguishes it from singular tools like get_cve or get_cwe by emphasizing the aggregated, cross-referenced payload.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Composite CVE dossier in one call' gives clear context for when this tool is appropriate: when you need a broad CVE intelligence bundle rather than a single detail. It does not explicitly name alternative tools or exclusion conditions, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_cweGet CWEARead-onlyIdempotent
Look up a CWE by identifier (e.g. CWE-79): weakness name, description, abstraction, MITRE likelihood_of_exploit, common consequences, detection methods, phased mitigations, related CWEs, the corpus threats that carry it, and related_cves - the corpus CVEs mapping to this weakness (top 20 by KEV then CVSS, with related_cve_count giving the true total; use search_vulnerabilities with cwe= for the full list). NOTE: CWE has no CVSS severity - likelihood_of_exploit is the ontology's own High/Medium/Low rating, and severity_note says so; for scored severity read the related_cves rows or call get_cve. related_cves is null (never []) if the join could not run.
| Name | Required | Description | Default |
|---|---|---|---|
| cwe_id | Yes | CWE identifier (e.g. CWE-79) |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| cwe_id | Yes | |
| enriched | No | False when not found — then only cwe_id is present. |
| threat_ids | No | |
| abstraction | No | |
| description | No | |
| mitigations | No | |
| related_cves | No | Corpus CVEs mapping to this CWE (top 20, KEV then CVSS). NULL means the join could not run — it never means "none exist"; [] does. |
| related_cwes | No | |
| severity_note | No | |
| detection_methods | No | |
| related_cve_count | No | True total mapping to this CWE, which can exceed the 20 returned. |
| related_cves_note | No | |
| common_consequences | No | |
| likelihood_of_exploit | No | MITRE's High/Medium/Low rating. CWE has NO CVSS severity — see severity_note. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though readOnlyHint and idempotentHint already establish the operation is a safe lookup, the description adds important non-obvious behavior: CWE has no CVSS severity, likelihood_of_exploit is the ontology's own rating, related_cves is limited to top 20 with related_cve_count as the true total, and related_cves may be null when the join fails. This volume of field-level caveats goes well beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense with useful information and has no filler, but it is written as a long run-on paragraph with many embedded caveats, making it harder to parse than it needs to be. It is front-loaded with the core action and purpose, but the structure could be improved with short clauses or separation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only lookup with one parameter and an output schema, the description covers everything an agent needs: input format, available fields, related-tool routing, the CWE-vs-CVE severity distinction, and exceptional return values. No obvious behavioral gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The parameter cwe_id is already fully documented in the schema with the exact format ('CWE identifier (e.g. CWE-79)'), and the description only repeats that same format without adding normalization rules or boundary cases. Since schema_description_coverage is 100%, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise directive — 'Look up a CWE by identifier' — and distinguishes this from CVE-related tools by explicitly noting that CWE has no CVSS severity and directing severity-seeking callers to related_cves or get_cve. It also names the sibling search_vulnerabilities for a fuller CVE list, so the tool is clearly scoped among its siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives actionable routing guidance: use this tool for CWE details, switch to get_cve for scored severity, and use search_vulnerabilities with cwe=<id> for the complete list of related CVEs. These explicit alternatives and conditions leave little ambiguity about when to select this tool over siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_d3fend_postureD3FEND PostureARead-onlyIdempotent
Get the defensive twin of a threat's ATT&CK mapping: offensive technique to digital artifact to D3FEND countermeasure, plus coverage by defensive tactic. Use to answer 'what would have stopped this'. COVERAGE: 197 of 1,891 threats carry a mapping, so absence is common and is not an error — a threat that exists with no mapping answers 200 with an empty mappings and a reason saying whether it has no techniques at all or techniques the ontology has no countermeasure for; only an unknown threat id answers 404. IMPORTANT: this is a deterministic projection of the threat's techniques through a static ontology — two threats sharing countermeasures almost always just share techniques, so never treat countermeasure overlap as independent correlation evidence.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Raw technique x countermeasure pairs in `mappings` (default 60, max 500). `countermeasures` always rolls up ALL pairs regardless, so the default loses no information — raise this only if you need the individual pairings. | |
| threat_id | Yes | Threat ID (e.g. TL-2026-1916) |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | TOTAL technique x countermeasure pairs, not the number returned in `mappings`. |
| error | No | Present only on 404 ('threat not found'). A threat that exists but has no mapping answers 200, never 404. |
| caveat | No | States that this is a deterministic projection of threat_mitre, not independent evidence. |
| reason | No | Present only on the 200-with-zero-mappings case: says WHY there is no posture (no techniques mapped vs techniques with no countermeasure). |
| coverage | No | |
| mappings | No | |
| threat_id | Yes | |
| detail_hint | No | |
| countermeasures | No | |
| mappings_returned | No | |
| mappings_truncated | No | True when `mappings` was capped; `countermeasures` still covers every pair. |
| countermeasure_count | No | |
| offensive_technique_count | No | Distinct ATT&CK techniques on the threat — the denominator the projection ran over. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/idempotent annotations by explaining the deterministic nature of the projection, the 197-of-1,891 coverage rate, the 200-with-empty-mappings case, why that absence is not an error, and when a 404 is actually returned. This is exactly the behavioral nuance an agent needs beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence in the description carries load: the core purpose, the coverage limitation, the empty-vs-notch response, and the interpretive caveat. The COVERAGE and IMPORTANT markers make the longer text easier to parse, and the most actionable guidance appears first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With only one required param and a complete output schema, the description still covers the full behavior: the default result, rare-empty state, the 404-only condition, and the fatal conclusion. There is no ambiguity left for an agent in interpreting either a result or an error from this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents threat_id format and limit's default, max, and behavior. The description adds no new parameter-level meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get') and a concrete resource: the defensive twin mapping from ATT&CK technique to artifact to D3FEND countermeasure, with coverage by defensive tactic. The scope is unique among the sibling tools and directly answers 'what would have stopped this'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to use it for 'what would have stopped this' and gives clear behavior expectations: absence of a mapping is common and not an error, and countermeasure overlap must not be treated as correlation evidence. It does not name any alternative sibling tool, so the 'vs alternatives' guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_daily_intel_bundleDaily Intel BundleARead-onlyIdempotent
One-shot "what happened" bundle: the day's debrief (latest by default, or pass date) plus platform stats, the top recent threats as LEAN summary rows, and the correlations overview. Drill into any listed threat with get_threat(id).
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Debrief date YYYY-MM-DD (default: latest) | |
| top_n | No | How many top threats to include (default 5, max 10) |
Output Schema
| Name | Required | Description |
|---|---|---|
| debrief | No | |
| detail_hint | No | |
| top_threats | No | LEAN summary rows (the search_threats shape) — call get_threat(id) for a dossier. |
| platform_stats | No | |
| correlations_overview | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior, so the description does not need to repeat those guarantees. It adds behavior context by stating the latest-day default, the date override behavior, and the aggregate contents returned in the bundle. This is useful supplementary context and is fully consistent with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no wasted text, and it front-loads the tool's core purpose and composition. The second sentence is a high-value routing signal that helps the agent decide what to do after receiving the bundle. Every part of the description earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero required parameters, a rich output schema, full schema description coverage, and read-only/idempotent annotations, the description is sufficiently complete. It explains what the response will contain, how to customize it via date, and what to do next for more detail on a threat.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes both parameters with 100% coverage, so the description only needs to add marginal semantic value. It adds 'latest by default, or pass date' for date and summarizes top_n as 'top threats as LEAN summary rows,' but this mostly restates default semantics that a capable agent can already derive from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a one-shot aggregate 'what happened' bundle composed of a debrief, platform stats, top recent threats, and correlations. It names a concrete resource category that an agent can distinguish from single-purpose sibling tools like get_debrief or get_correlations, and it even points to a complementary sibling, get_threat, for drill-down.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'One-shot what happened bundle' gives a clear contextual use case: use this for a consolidated daily situational snapshot in a single call. It does not exhaustively contrast this with similar aggregate siblings such as get_landscape_briefing or get_threat_bundle, but it does provide useful routing guidance by saying to use get_threat(id) when more detail on a listed threat is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_daily_themeDaily ThemeARead-onlyIdempotent
Get the recent daily landscape themes (newest first, 14 days) with each day's top 6 threat tags. tags is recomputed LIVE over that date's threats, ranked count-descending with an alphabetical tie-break, and tags_source says whether a row used the live rollup ('live'), the stored nightly snapshot ('snapshot') or had no tags at all ('none') — tags_available is the boolean. The theme SENTENCE is generated just after midnight ET, before the day's ingest finishes, so theme_note/snapshot_threat_count disclose how many of the day's threats it was actually written from; when they disagree, trust tags.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| themes | No | |
| tags_note | No | |
| yesterday | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses subtle behaviors that annotations cannot capture: tags are recomputed live, tags_source distinguishes live/snapshot/none, and the theme sentence may be generated before ingest finishes, making snapshot_threat_count and theme_note potentially inconsistent. It also gives trust guidance: when they disagree, trust tags. This exceeds the baseline provided by annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense, purposeful sentences each deliver a distinct semantic point: the core data scope, the live/snapshot/no-tag distinction, and the stale-theme caveat. The most important information is front-loaded first and the description contains no wasted wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-argument read tool, the description covers ordering, time horizon, ranking rules, tie-breaking, field provenance, staleness, and a trust heuristic, leaving no call-critical question unanswered. The output schema can fill in exact field names, so no missing return-value explanation is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
This tool has zero parameters, so there is no input-schema ambiguity for a description to resolve. The description appropriately devotes its space to output semantics rather than parameter details, matching the baseline for a no-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Begins with a concrete verb and resource: 'Get the recent daily landscape themes', immediately scoped by 'newest first, 14 days' and 'top 6 threat tags'. This makes the tool's identity and output unmistakable and clearly differentiates it from other daily-intel sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is strongly implied: call this when you need recent daily landscape themes with associated threat tags. However, it does not explicitly say when to prefer this over similar intel-read siblings such as get_landscape_briefing or get_daily_intel_bundle, so there is no direct alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_debriefGet DebriefARead-onlyIdempotent
Get the full daily intelligence debrief for a specific calendar date (YYYY-MM-DD): posture summary, themes, threats grouped by severity, MITRE coverage, IOC distribution, actor attribution, and detection status. Find available dates first with list_debriefs.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Debrief date in YYYY-MM-DD format (e.g. 2026-05-30) |
Output Schema
| Name | Required | Description |
|---|---|---|
| date | No | |
| stats | No | |
| title | No | |
| themes | No | |
| summary | No | |
| threats | No | |
| highlights | No | |
| new_threats | No | |
| new_detections | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnly, idempotent, and non-destructive behavior, so safety is covered. The description adds valuable context about the output structure (posture summary, themes, threats grouped by severity, etc.), which is not redundant with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences deliver the core purpose, output contents, and a prerequisite instruction. No redundant wording; highly efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and annotations cover safety, the description is complete for an agent to invoke. It lists the debrief sections and the necessary prerequisite step, making it sufficient for correct use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully documents the date parameter with format and example (100% coverage). The description only repeats the YYYY-MM-DD format, adding no new semantic information beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a full daily intelligence debrief for a specific calendar date, listing its contents (posture summary, themes, threats, etc.). It differentiates from sibling tools like list_debriefs and get_latest_debrief by emphasizing 'specific calendar date' and referencing the prerequisite list_debriefs call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly directs users to first call list_debriefs to find available dates, providing a clear usage guideline. It does not enumerate all alternative tools, but the instruction implies this is the tool for a specific date rather than the latest debrief.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_detection_detailGet Detection DetailARead-onlyIdempotent
Get the full detail for one detection rule by its ID, including the complete query text (SPL/KQL/Sigma), metadata, and the threat it maps to.
| Name | Required | Description | Default |
|---|---|---|---|
| detection_id | Yes | Detection ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| query | No | |
| severity | No | |
| kql_query | No | |
| threat_id | No | Pass to get_threat. |
| sigma_rule | No | |
| threat_title | No | |
| mitre_mapping | No | |
| detection_type | No | |
| false_positives | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint=true, idempotentHint=true, destructiveHint=false, which fully cover the safety profile. The description adds value by specifying the returned content depth (complete query text, metadata, threat mapping) beyond simple read semantics. However, it doesn't discuss behaviors like what happens with an invalid/unknown detection_id, rate limits, or whether the full query text is ever truncated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One tightly-written sentence that covers purpose, scope, and returned content without waste. Every element earns its place — the query-format enumeration (SPL/KQL/Sigma) is valuable detail packed into few words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, extensive annotations, and a single well-documented parameter, so the description's job is modest. It competently communicates what's returned (full query text, metadata, threat mapping). Minor gap: no mention of how a missing/unknown ID is handled or fallback behaviors, but for a read-only single-fetch tool with strong structured metadata, this is largely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter detection_id is simply documented as 'Detection ID'. The description reinforces the parameter's role (the ID of the detection to fetch) but adds no format, source, or usage detail beyond what the schema provides. With full schema coverage, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches full detail for a single detection rule by ID, enumerating specific content included (query text in SPL/KQL/Sigma, metadata, threat mapping). The verb 'Get' plus resource 'detection detail' is specific and distinct from siblings like get_detections (which lists detections) and search_detections (which searches).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this is for retrieving a single detection when you have a specific ID in hand, contrasting implicitly with get_detections (bulk listing) and search_detections (searching). It doesn't explicitly name alternative tools for when NOT to use it, but the single-ID parameter and 'full detail' framing make context reasonably clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_detectionsGet DetectionsARead-onlyIdempotent
List detection logic (Splunk SPL, Microsoft KQL, Sigma). Optionally filter by threat_id or detection type. Paginated: pass limit (default 15, max 100) and offset to page; the result includes has_more and an opaque next_cursor (reusable as offset/cursor).
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Detection type: spl, kql, or sigma | |
| limit | No | Max results (default 15, max 100) | |
| cursor | No | Opaque pagination cursor (next_cursor from a prior result). Decoded to an offset; ignored when offset is given. | |
| offset | No | Row offset for pagination (default 0). Or pass cursor from a prior result. | |
| threat_id | No | Filter detections for a specific threat ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| total | No | Total matching rows, when the handler reports one. |
| has_more | No | True when another page may exist. |
| next_cursor | No | Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is established. The description adds valuable behavioral context: pagination mechanics (has_more, next_cursor reusable as offset/cursor) and the specific precedence rule (cursor ignored when offset given). This enriches the annotation-based safety signals with concrete runtime behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three efficient sentences with zero wasted words. Front-loads the core purpose, then filters, then pagination mechanics. Every clause adds information that isn't elsewhere, and the structure logically groups listing behavior, filtering, and pagination in order of importance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, which relieves the description of explaining return values. With 5 parameters, no required fields, pagination mechanics explained, and read-only idempotent semantics assumed from annotations, this is reasonably complete. Minor gap: doesn't name sibling alternatives (search_detections) for when broader search is needed, but the complexity is low enough that the description suffices.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all five parameters are documented in the schema. The description adds the relationship between cursor and offset (cursor decoded to offset, ignored when offset given), which is genuinely helpful beyond the schema. However, the individual parameter descriptions in the schema are already thorough; the description's contribution is mainly the cursor/offset interaction nuance, warranting baseline 3 rather than higher.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb+resource ('List detection logic') and enumerates the content formats (Splunk SPL, Microsoft KQL, Sigma). It distinguishes from siblings like search_detections (which implies a search action) and get_detection_detail (singular detail) by specifying this is a listing operation with filters. Clear differentiation from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clarifies pagination behavior and mentions optional filtering by threat_id or type, giving clear usage context. However, it doesn't explicitly contrast with search_detections or get_detection_detail, nor state when to prefer this over those alternatives. The pagination guidance is strong but sibling differentiation is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_engine_statusIntelligence Engine StatusARead-onlyIdempotent
Is the intelligence pipeline healthy? Per-engine row counts, last-compute times and derived ok/stale/empty status; the nightly graph pipeline's staged progress, current stage and degraded flag; recent failures; and the latest held-out accuracy eval (AUC). Check this before reasoning over correlation output if freshness matters.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| eval | No | |
| engines | Yes | |
| failures | No | |
| generated_at | No | |
| graph_pipeline | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is established. The description adds value by disclosing the tool is a status/health read that returns state rather than data, and enumerates the derived statuses (ok/stale/empty) and pipeline metadata that compose the response. This complements rather than duplicates the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler. The first sentence densely enumerates the return payload using semicolon-separated clauses, and the second gives one actionable directive. Every word earns its place with no rhetorical padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless, read-only status tool with no nested objects, an output schema, and full annotations, the description is complete. It not only lists the payload categories but also the derived status vocabulary and the use-case context. There is an output schema to define return structure, so the description need not duplicate field details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline is 4 per the rubric. The description appropriately focuses on describing what the tool returns instead of parameter usage, which is the correct approach for a parameterless tool. No parameter documentation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific interrogative about pipeline health and enumerates exactly what is covered: per-engine row counts, last-compute times, ok/stale/empty status, nightly graph pipeline progress/stage/degraded flag, recent failures, and latest AUC eval. It clearly distinguishes from siblings like health and get_platform_stats by specifying the concrete data points returned.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The final sentence gives explicit guidance: 'Check this before reasoning over correlation output if freshness matters.' This is a clear when-to-use directive tied to a specific downstream workflow (correlation reasoning). Though it does not name alternative tools, it provides actionable context for when this check is warranted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_enrichment_overviewEnrichment OverviewARead-onlyIdempotent
Health and coverage of the enrichment LANES feeding the platform, one row each: cve_details, threat_iocs, detections, mitre_attack, c2_intel, dns_enrichment, tl_osint_scan, osint_blocklist_liveness. EPSS and KEV are NOT separate lanes - they are fields inside cve_details (whose hit_rate is the share of CVEs carrying both CVSS v3 and EPSS), and there is no IOC-reputation lane; the nearest signals are osint_blocklist_liveness and tl_osint_scan. Each lane's hit_rate has its OWN definition (they are not comparable to each other) and coverage_basis distinguishes 'measured_zero' from 'not_measured' - c2_intel really is 0% corpus coverage, because c2_correlations_v2 has no populated threat_id. This is a nightly snapshot: read as_of/stale_hours before treating it as current.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | States which advertised sources are lanes and which are fields of a lane. |
| as_of | No | Newest row timestamp - this is a nightly snapshot, not a live read. |
| sources | No | |
| summary | No | |
| stale_hours | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already state that this is read-only, idempotent, and non-destructive. The description adds meaningful behavioral context beyond those annotations: the output is a nightly snapshot, the data is grouped into specific lanes, coverage_basis distinguishes 'measured_zero' from 'not_measured', and c2_intel's 0% is explained as a true omission rather than a measurement artifact. This is exactly the kind of interpretive detail an agent needs to avoid misreading the data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense but every sentence earns its place: the row set, the non-lane caveats, the hit_rate caveat, the measured-zero explanation, and the freshness warning. It is front-loaded with the main purpose and then adds necessary exclusions and interpretation guidance. There is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter, output-driven tool, this description covers all the essential context an agent needs: what the overview reports, how the rows/lines are defined, what fields like hit_rate and coverage_basis actually mean, and how to check freshness. The output schema is already available, so the description does not need to re-list the return shape. No important usage aspect seems missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no schema surface for the description to clarify. The description instead clarifies the semantics of the returned object, which is more than enough for an empty input schema. Since there are no parameters to describe, the baseline of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a very specific resource: 'Health and coverage of the enrichment LANES feeding the platform,' and immediately enumerates the exact rows/groups the tool returns. It also clarifies what is not included (EPSS and KEV are fields inside cve_details, not separate lanes), which removes ambiguity an agent would otherwise have when deciding whether this matches the user's request.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong context on how to interpret the result: values like coverage_basis have special meanings, hit_rate definitions vary by lane, and c2_intel's 0% is a true measured zero. It also cautions the agent to read as_status/stale_hours because this is a nightly snapshot. It does not explicitly name alternative sibling tools or a when-not-to-use condition, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_entity_aliasesEntity Aliases (reverse)ARead-onlyIdempotent
Every alias the reference set maps to ONE entity — the reverse of resolve_entity, which only walks a single alias forward. Use it to check alias collision: the commonest reason two "different actors" turn out to be one. IMPORTANT: the source (MISP) OVER-MERGES — it folds subgroups into their parent, so "andariel" and "bluenoroff" both appear under "Lazarus Group". An alias entry is a MAPPING, not an assertion of identity. Each alias therefore carries relation (canonical|subgroup|alias), other_entities (how many other entities claim the same label) and corpus_threats (how many threats this platform files under that exact label); corpus_uses_separately lists labels the corpus treats as their own actor despite the merge. Accepts a name or a uuid.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Name or alias to expand (e.g. "andariel"). Resolved exact-then-fuzzy, same ladder as resolve_entity. | |
| type | No | Optional: actor|malware|tool|sector|region|technique|campaign — narrows name resolution. | |
| uuid | No | Entity uuid, if you already have one from resolve_entity. Skips resolution. |
Output Schema
| Name | Required | Description |
|---|---|---|
| uuid | No | |
| caveat | No | Over-merge warning. Do not drop it when summarising. |
| aliases | No | |
| cluster | No | |
| matched | Yes | |
| canonical | No | |
| alias_count | No | |
| entity_type | No | |
| matched_via | No | uuid | exact | fuzzy |
| corpus_uses_separately | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare a safe read, but the description adds material behavior: the data source over-merges subgroups, alias entries are mappings not identity assertions, and relation/other_entities/corpus_uses_separately carry distinguishing semantic meaning. This is valuable context the annotation schema cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: reverse relationship, usage guidance, data-quality warning, key output semantics, and accepted inputs. The structure front-loads the differentiating relationship and remains dense without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the description need not restate return formats; instead it provides the conceptual semantics that make the results interpretable, plus the over-merge warning that affects correct reasoning. It is complete for an agent deciding whether and how to invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 and the schema already documents name, type, and uuid well. The description matches the input fields but adds no meaningful parameter details beyond what the schema states; its extra content is about output semantics and caveats.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb and resource ('Every alias the reference set maps to ONE entity') and explicitly contrasts it with resolve_entity, which 'only walks a single alias forward.' This immediately distinguishes it from a close sibling and makes the reverse-relationship clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the exact use case ('Use it to check alias collision') and the alternative tool (resolve_entity), while explaining how this tool differs and the common failure it addresses. The MISP over-merging caveat also tells the agent when the data may be misleading.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_entity_profileEntity ProfileARead-onlyIdempotent
One-call dossier for any node in the intelligence graph — threat, technique, actor, IOC or CVE. Returns its centrality/pivot rank, top graph neighbours with edge fidelity, and type-specific rollups (linked threats, techniques with risk scores, IOCs with consensus and rarity, campaigns, related CVEs). Best token-per-call ratio in the graph family: replaces five or six separate lookups. Neighbours on the NPMI edge types also carry raw pmi, co_occurrence_count and the marginals {c, df_actor, df_tech, N}. For technique and ioc nodes the response includes rarity — corpus_df (how many threats mention it) against corpus_n — which is what separates a distinctive shared technique from background noise; check top_neighbors_truncated and raise limit before concluding a neighbour is absent.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Neighbours in top_neighbors (default 20, max 100 over MCP). They are ordered by fidelity, so the rare low-fidelity edges are the ones a small limit drops. | |
| node_id | Yes | The entity id/value (TL- id, T-number, actor name, IOC value, or CVE id). | |
| node_type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| cves | No | |
| iocs | No | |
| node | Yes | |
| rarity | No | |
| threats | No | |
| campaigns | No | |
| techniques | No | |
| top_neighbors | No | |
| top_neighbors_limit | No | |
| top_neighbors_truncated | No | True when more neighbours exist than were returned — raise `limit`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive. The description adds genuinely useful behavior beyond those annotations: NPMI edges carry raw pmi/co-occurrence/marginal values, rarity is defined in terms of corpus_df vs corpus_n, and top_neighbors_truncated can hide low-fidelity neighbors unless limit is raised. This is transparent about an easy-to-misread response behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and information-dense: the first sentence defines the core purpose, and the following sentences add high-value details like the NPMI payload, rarity semantics, and truncation caveat. It is somewhat long and technical, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema, annotations, a moderate parameter list, and strong parameter descriptions, the description supplies the missing context about return content, edge fields, rarity interpretation, and pagination/limit caveats. For a complex intelligence-graph endpoint, nothing essential for correct invocation appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, with node_id and limit already described, and node_type sufficiently conveyed by its enum. The description adds real parameter value: it explains how limit interacts with fidelity ordering, which matters because low-fidelity edges are the first dropped. It also contextualizes the node_id values across node types. This exceeds the baseline without fully replacing the schema's per-parameter detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a one-call dossier for any intelligence-graph node, naming the supported node types (threat, technique, actor, IOC, CVE). It distinguishes itself from the many sibling getters such as get_threat/get_actor/get_cve by claiming to replace five or six separate lookups, so an agent can select it with confidence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when to use it: when a consolidated overview with neighbors, rankings, and type-specific rollups is needed, and that it is the best token-per-call option in the graph family. It also gives practical guidance about checking top_neighbors_truncated and raising limit before concluding a neighbor is absent. It does not explicitly name alternatives or give when-not-to-use conditions, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_flow_coverageFlow CoverageARead-onlyIdempotent
How much of the corpus carries an authored ATT&CK Flow, split by provenance, plus flow node/transition/path-similarity totals and whether the flow similarity channel has met its coverage gate. Call this before reasoning over flow data so you know the denominator — flow-derived findings only speak to the covered slice.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| flows | Yes | |
| channel | No | |
| threats | Yes | |
| authored | No | Flows with generator='harness'. Only these assert causality. |
| flow_nodes | No | |
| by_generator | No | |
| coverage_pct | Yes | Authored flows as a percentage of the corpus — the denominator for any flow-derived claim. |
| flow_transitions | No | |
| path_similarity_pairs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds useful interpretation context: flow-derived findings only apply to the covered portion of the corpus, and clarifies the special gate semantics, which is beyond annotation content.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded about the returned information; the second sentence provides the operational instruction. There is no redundant wording or unnecessary schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-input, read-only tool with an output schema and annotations, the description provides enough context about what coverage means, how it is split, and when to call the tool. No essential guidance is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description is not expected to document parameter semantics. Schema already covers the entire parameter surface.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool reports: corpus-wide ATT&CK Flow coverage split by provenance, plus totals for nodes, transitions, and path similarity, and the coverage-gate status. It is specific and reader can distinguish it from siblings like get_attack_flow and get_mitre_coverage, though it doesn't explicitly name an alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to call this tool before reasoning over flow data so that findings are correctly interpreted against the covered slice. It gives clear usage context, but it does not state explicit when-not-to-use conditions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_flow_similar_threatsFlow-Similar ThreatsARead-onlyIdempotent
Find threats that share a causal SEQUENCE of techniques with this one, scored by ordered-bigram cosine over ATT&CK Flow transitions. This sees what no other channel can: every existing similarity signal compares flat sets, so two threats can share an identical attack ORDER while sharing no indicator, CVE or actor. Returns the shared transitions (e.g. 'T1003>T1021') so the claim is inspectable. Scored independently and NOT folded into get_similar_threats' blended score.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max neighbours (default 20, max 100) | |
| min_score | No | Drop neighbours below this sim_flow (0-1) | |
| threat_id | Yes | Threat ID (e.g. TL-2026-1916) |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| reason | No | Present only when data is empty; distinguishes "no flow published" from "flow published, no neighbours". |
| threat_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds meaningful behavioral detail beyond annotations: the scoring algorithm, the ATT&CK Flow transition concept, and the expectation that it returns inspectable shared transitions like 'T1003>T1021'. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the core operation, the uniqueness explanation, the return contract, and the independence from get_similar_threats. It is front-loaded with the primary verb and resource, and there is no padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With the output schema present, parameter meanings fully documented, and annotations covering side effects, the description is complete enough for an agent to successfully call this tool. The remaining constraints like min_score and limit are already captured in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with meaningful definitions already provided for threat_id, limit, and min_score. The description does not need to restate parameter details, and it does not meaningfully expand beyond what the schema says. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the specific action: finding threats that share a causal SEQUENCE of techniques, using ordered-bigram cosine over ATT&CK Flow transitions. It also distinguishes this tool from the sibling similarity tool by explicitly stating its score is NOT folded into get_similar_threats' blended score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context on when this tool is valuable: when attack ORDER matters and flat-set similarity signals are insufficient. It names get_similar_threats as the alternative and contrasts its blended scoring, but it stops short of explicitly listing when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_graph_campaignsGraph CampaignsARead-onlyIdempotent
Campaign clusters the engine assembled from the similarity graph (connected components + label propagation): label, cohesion, top actors/techniques/IOCs/nation-states, and per-member {title, created_at, category, threat_actor}. Each cluster carries duplicate_risk plus its evidence (distinct_member_dates, date_span_days, shared_title_tokens) — a similarity-derived cluster of one event documented several times looks identical to a real multi-event campaign until you read those. Distinct from get_campaign_intelligence (looks up a NAMED campaign from threat text) and from list_campaigns (the roster of named campaigns); this one reports clusters the engine derived itself.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 15, max 50. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| summary | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds value beyond annotations by warning that a cluster of one event documented multiple times can look identical to a real multi-event campaign until the agent reads the duplicate_risk evidence fields (distinct_member_dates, date_span_days, shared_title_tokens). That is non-obvious behavioral context which prevents an agent from misinterpreting results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core identity of the tool is front-loaded ('Campaign clusters the engine assembled from the similarity graph'), and the differentiation from sibling tools comes in a clearly marked second sentence. The first sentence is dense with enumerations, but each item corresponds directly to actual return fields, so there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one documented parameter and an output schema, the description fully explains the resource's origin, content, cluster semantics, the duplicate_risk caveat, and the naming neighbor tools. No information needed to call it correctly or interpret its output is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — the only parameter, limit, already carries a full schema description (default 15, max 50). The description adds nothing parameter-specific, but it does not need to; the schema fully documents the single input.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb ('reports') and a well-scoped resource: campaign clusters the engine derived itself from the similarity graph (connected components + label propagation), with an explicit list of contents (label, cohesion, actors, techniques, IOCs, nation-states, per-member fields). It also differentiates itself from get_campaign_intelligence and list_campaigns, making the tool distinguishable from its closest siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit routing rules: use get_campaign_intelligence when looking up a NAMED campaign from threat text, use list_campaigns for the roster of named campaigns, and use this tool for the clusters the engine derived itself. Each alternative is named with a criterion that selects it, leaving the agent with no inference to make.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_infrastructure_pivotsInfrastructure PivotsARead-onlyIdempotent
For a given threat, surface cross-threat infrastructure links — shared IPs/domains/hashes and DNS-derived overlaps that tie it to other campaigns. Derived from the SAME indicator universe the correlation graph scores, so a pivot here and an ioc-basis edge in explain_correlation agree. Each pivot carries value_threat_count (2 = the value is nearly unique to this pair; 40 = commodity such as a Run key) and a rarity-derived confidence — read those before calling an overlap a link. coverage gives the denominator: pivot_count 0 with scorable_iocs > 0 is a REAL negative, pivot_count 0 with scorable_iocs 0 only means the threat carries no pivotable indicator. Labels (malware family, tool name, technique) are deliberately not pivotable — two write-ups naming the same family observed nothing in common. Use get_similar_threats for TTP/actor-based similarity instead.
| Name | Required | Description | Default |
|---|---|---|---|
| threat_id | Yes | Threat ID (e.g. TL-2026-0042) |
Output Schema
| Name | Required | Description |
|---|---|---|
| coverage | No | |
| dns_trail | No | |
| threat_id | Yes | |
| pivot_count | No | |
| dns_record_count | No | |
| infrastructure_pivots | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, idempotentHint, destructiveHint), it explains important behavioral details: results derive from the same indicator universe as the correlation graph, pivots carry value_threat_count thresholds, and confidence is rarity-based. It also clarifies a real semantic trap — that zero pivots can mean either a genuine negative or merely no pivotable indicators, and that labels are excluded by design so the returned evidence is not overstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads the primary purpose and then earns every subsequent sentence with real-value guidance: value_threat_count interpretation, coverage semantics as denominator, and when to route to get_similar_threats. It is dense but appropriately so for a tool whose output requires careful interpretation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is one required parameter, an output schema is present, and independent annotations already cover read-only/idempotent safety. The description supplies the missing interpretive context — how to read pivot_count/value_threat_count and why zero results can still be meaningful — making this complete for the agent to invoke and consume the tool responsibly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already gives 100% coverage of the only parameter, threat_id, with a format example. The description adds no additional parameter detail beyond framing it as the 'given threat,' so the baseline of 3 applies; the schema is doing the heavy lifting here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: "surface cross-threat infrastructure links" for a given threat, listing the exact artifacts involved (IPs, domains, hashes, DNS overlaps). It differentiates itself from get_similar_threats by explicitly disclaiming TTP/actor-based similarity, leaving no ambiguity about scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says when to use it (to find shared infrastructure across threats) and when not to ('labels are deliberately not pivotable') with a direct pointer to the alternative: 'Use get_similar_threats for TTP/actor-based similarity instead.' It also tells the caller how to interpret edge cases like pivot_count=0 with scorable_iocs > 0 vs = 0.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ioc_blast_radiusIOC Blast RadiusARead-onlyIdempotent
Map the blast radius of one indicator: the threats that contain it, the MITRE techniques those threats use, and the actors + sibling IOCs in the same campaigns. Matching is case-insensitive, and for a CVE the threat ring is the UNION of indicator rows and threats.cve_list (the authoritative CVE-to-threat mapping) — coverage reports which of the two produced how many, so a count can be traced to its source. edge_scores is a sampled graph_edges projection for fidelity context, never the denominator. Use this to scope impact of a single IOC; for a richer multi-source dossier on one indicator use get_ioc_intelligence instead.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Traversal rings to expand (1–3, default 3): 1=threats, 2=+techniques, 3=+actors & sibling IOCs | |
| value | Yes | Indicator value (IP, domain, hash, URL, or CVE-XXXX-NNNN) |
Output Schema
| Name | Required | Description |
|---|---|---|
| rings | No | |
| stats | No | |
| center | Yes | |
| coverage | No | |
| edge_scores | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly and idempotent, so the safety profile is covered. The description adds critical behavior beyond that: case-insensitive matching, CVE union semantics from two sources, authoritative CVE-to-threat mapping, and the caveat that edge_scores is a sampled projection and never the denominator for counts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each dense with necessary information and no filler. The core purpose is front-loaded, and the behavioral caveats are organized logically.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a moderately complex but bounded tool: it explains inputs, depth semantics, matching behavior, edge probabilities, CVE-specific union logic, and tool alternatives. An output schema exists, so detailed return values do not need to be restated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. However, the description adds meaningful elaboration: it defines depth traversal rings concretely (1=threats, 2=+techniques, 3=+actors & sibling IOCs) and clarifies the meaning of coverage and edge_scores in the output, going beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Map the blast radius'), a precise resource ('one indicator'), and enumerates the output dimensions (threats, MITRE techniques, actors, sibling IOCs). It also differentiates itself from the closest sibling by explicitly saying get_ioc_intelligence is for a richer multi-source dossier.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this to scope impact of a single IOC' and names the alternative for a richer dossier on one indicator (get_ioc_intelligence). This gives the agent clear selection criteria and an exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ioc_dnsIOC DNS EnrichmentARead-onlyIdempotent
Return stored DNS enrichment for an IP or domain indicator (reverse-IP and subdomain records previously resolved and cached in the platform dataset). This reads stored data — it is NOT a live lookup at call time. Use get_ioc_intelligence for the full stored dossier.
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | IP address or domain (stored DNS enrichment lookup) |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | No | |
| domains | No | |
| cross_links | No | |
| query_value | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well covered. The description adds meaningful context beyond these annotations: it clarifies that the data is 'previously resolved and cached' and explicitly flags that this is NOT a live lookup — a key behavioral caveat not captured by any annotation. Minor deduction for not describing the output format beyond 'reverse-IP and subdomain records.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences and tightly written with zero filler. It front-loads purpose in the first sentence, adds the critical non-live caveat in the second, and points to the alternative in the third. Every sentence earns its place. Minor deduction only because the parenthetical 'reverse-IP and subdomain records' could arguably be integrated more cleanly, but this is essentially optimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool is a simple single-parameter read operation with comprehensive annotations (readOnly, idempotent, non-destructive) and an output schema present, the description is largely complete. It covers the stored-vs-live distinction, the input scope, and points to the richer sibling. Context signals show only 1 parameter, 100% schema coverage, and presence of an output schema, all of which reduce the descriptive burden. Could add pagination/limits info for many-record DNS results, but that's speculative.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single required parameter 'value' has a clear description ('IP address or domain'). The main description reinforces the acceptable input types. Since the schema already documents the parameter fully, the baseline of 3 applies — the description adds slight value by phrasing it as 'stored DNS enrichment lookup' but not much beyond schema. There's only 1 parameter, so there's little semantic ambiguity to resolve.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool does: 'Return stored DNS enrichment for an IP or domain indicator.' It specifies the resource (stored DNS enrichment), the scope (IP or domain), and explicitly differentiates from siblings ('Use get_ioc_intelligence for the full stored dossier'). The verb 'Return' plus resource is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly notes this is a read of stored/cached data, NOT a live lookup at call time, which prevents misuse. It also names the alternative get_ioc_intelligence for a fuller dossier, giving clear when-to-use vs when-not guidance. This is exceptional usage guidance for a retrieval tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ioc_intelligenceIOC Intelligence DossierARead-onlyIdempotent
Get the composite intelligence dossier for one indicator: linked threats, actor attribution, related IOCs, and enrichment context in a single call. Prefer this over search_iocs when you already have an exact indicator value and want its full story.
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | Exact indicator value (IP, domain, hash, or URL) |
Output Schema
| Name | Required | Description |
|---|---|---|
| osint | No | |
| threats | No | |
| ioc_value | Yes | |
| truncated | No | |
| dns_records | No | |
| threat_count | No | |
| consensus_score | No | Multi-feed consensus; null when no feed has seen it. |
| infrastructure_pivots | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is established. The description adds the composite-content framing and that it returns 'full story' in a single call, which is marginally useful context. It doesn't note rate limits, data freshness, or what happens for unknown indicators, but with strong annotations the bar is met at a moderate level.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both earning their place. The first states what the tool returns; the second gives routing guidance with a sibling alternative. Zero filler, front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation isn't needed. With strong annotations (read-only, idempotent), strong schema (100% coverage), and one simple parameter, the description covers the essential context. It could potentially mention what happens with an unrecognized indicator, but for a single-param read-only dossier tool, this is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the 'value' parameter as an exact indicator value (IP, domain, hash, or URL). The description reinforces that a single exact indicator is expected, which aligns with the schema. Since the schema does the heavy lifting, baseline 3 is appropriate; the description adds little beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Get'), resource ('composite intelligence dossier'), and scope ('for one indicator'), then enumerates contents: linked threats, actor attribution, related IOCs, and enrichment context. It also distinguishes itself from the sibling search_iocs by clarifying it works with an exact indicator value. This is a specific, well-defined purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly directs to prefer this over search_iocs when an exact indicator value is available and full context is needed. This implies search_iocs is for broader/fuzzy searches. Naming the alternative tool with a clear when-to-use rule is exactly what dimension 2 rewards.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_landscape_briefingLandscape BriefingARead-onlyIdempotent
Get the latest threat-landscape briefing — a synthesized posture summary of recent threat activity. latest is the most recent briefing that is a REAL synthesis: the narrative model currently fails on most hourly runs, and a failed run still writes a one-bullet automated posture stub, so the newest row is usually not a summary at all. When a fallback is served the response says so (latest_is_fallback + fallback_note naming both dates) and latest_age_hours gives its age; briefings[0] is always the newest regardless of quality, and every row carries is_synthesis. narrative_ok reports whether the newest run produced a real narrative.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| latest | No | The most recent REAL synthesis (see latest_is_fallback). |
| briefings | No | |
| page_size | No | |
| stub_count | No | |
| top_viewed | No | |
| narrative_ok | No | Did the NEWEST run produce a real narrative? |
| fallback_note | No | Names which date was served and which was skipped. |
| latest_age_hours | No | |
| latest_is_fallback | No | |
| latest_generated_at | No | |
| latest_is_synthesis | No | |
| newest_generated_at | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare the operation readOnly and idempotent, but the description adds significant non-obvious behavior: failed hourly runs still write a one-bullet posture stub, the newest row is usually not a genuine synthesis, and fallback status is exposed through fields like latest_is_fallback and narrative_ok. This is exactly the kind of appendix the model runtime an agent would never infer from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence delivers the core purpose, and the following sentences provide only high-value caveats and field names. Each piece adds actionable detail — the fallback condition, the fields that detect it, and the invariant that briefings[0] is the newest row. There is no filler and no duplication of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with no parameters and an output schema, the description covers the entire important decision surface: what the tool returns, when the newest row is unreliable, what fallback indicators exist, and how to determine whether the newest narrative is real. Nothing material is missing for correct invocation and interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter semantics for the description to elaborate. Schema coverage is effectively 100% and the 0-parameter baseline applies. The description correctly spends its limited length on response semantics rather than inventing parameter information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get the latest threat-landscape briefing' and defines it as 'a synthesized posture summary of recent threat activity.' It also clearly distinguishes the tool by explaining that the latest returned row is usually a fallback stub, not a real summary, which separates this tool from simpler briefing fetchers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when a latest landscape briefing is wanted and goes into depth about how to interpret the response. Nevertheless, it does not explicitly compare with related sibling tools such as get_latest_debrief or get_daily_intel_bundle, nor does it state when this tool should be preferred or avoided. Usage context is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_latest_debriefGet Latest DebriefARead-onlyIdempotent
Get the most recent daily intelligence debrief in full detail (resolves the latest date for you).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| date | No | |
| title | No | |
| latest | No | |
| summary | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds the behavioral detail that the tool internally resolves the most recent date, which is genuinely useful beyond annotations. With readOnlyHint=true, idempotentHint=true, and destructiveHint=false already declared, the safety profile is well covered. The description doesn't mention return format, but an output schema exists, lowering the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that covers purpose, the automatic date resolution behavior, and output detail level ('full detail'). Zero wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only, idempotent tool with an output schema present, the description is sufficiently complete. It conveys what it returns ('full detail'), how the date is handled, and the safety profile is covered by annotations. Minor gap: it doesn't note what time period the 'latest' refers to, but this is a minor omission for a straightforward fetch tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has 0 parameters, so there are no parameters to document. With schema description coverage at 100% (vacuously, since there are no parameters), the baseline would be 4 for zero-parameter tools. The description correctly confirms no inputs are needed by stating it resolves the date for you.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb+resource: 'Get the most recent daily intelligence debrief in full detail.' It adds the useful nuance that the tool resolves the latest date for the agent, distinguishing it from a debrief tool requiring an explicit date parameter. It doesn't explicitly name a sibling alternative, but the 'resolves the latest date for you' clause differentiates it from other debrief-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the use case (when you want the latest debrief without knowing/specifying a date), which provides reasonable context. However, it doesn't explicitly state when NOT to use it or name an alternative (e.g., a date-specific debrief tool if one existed). The implied usage is adequate but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_malware_intelligenceMalware IntelligenceARead-onlyIdempotent
Pivot on a malware FAMILY by name (e.g. "LockBit", "Vidar", "Emotet"). Returns the canonical family + type, prevalence (threat/actor counts, first/last seen), the threats deploying it, the actors using it, and its most-common ATT&CK techniques. For an offensive TOOL (Cobalt Strike, Mimikatz) use get_tool_intelligence instead. Call resolve_entity first if unsure of the canonical name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Malware family name (e.g. "LockBit", "Vidar") |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | No | |
| actors | No | |
| matched | Yes | |
| threats | No | |
| canonical | No | |
| membership | No | |
| prevalence | No | |
| entity_type | No | |
| top_techniques | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already establish readOnlyHint=true and idempotentHint=true, so the description does not need to repeat safety behavior. It adds genuinely useful behavioral context: the tool works from family names, resolves them to canonical entities, and returns prevalence plus related threats/actors/techniques. It does not describe error behavior for unknown names, but the output schema and read-only annotations lower the burden here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the first states purpose and input, the second lists return contents, and the third provides routing to the natural sibling. It is concise, front-loaded, and has no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one required parameter, an output schema, and annotations covering side effects, the description includes everything operationally important: what type of input is accepted, what results are produced, the appropriate alternative, and the recommended disambiguation step. No critical invocation detail is missing for an agent to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the only parameter 'name' at 100% coverage, so the baseline is 3. The description adds further meaning by clarifying that the value is a family, not a tool or actor, and by telling the agent to resolve non-canonical names beforehand. This gives the parameter real semantic depth beyond the schema example strings.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb and resource: 'Pivot on a malware FAMILY by name'. It lists concrete return contents (canonical family, type, prevalence, threats, actors, ATT&CK techniques) and distinguishes itself from get_tool_intelligence, so an agent can immediately separate it from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells when this tool is correct ('Pivot on a malware FAMILY') and when to choose the alternative: 'For an offensive TOOL (Cobalt Strike, Mimikatz) use get_tool_intelligence instead'. It also handles the ambiguous-name case by instructing 'Call resolve_entity first if unsure of the canonical name.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_mitre_coverageMITRE CoverageBRead-onlyIdempotent
Get MITRE ATT&CK coverage across the platform. Optionally filter by tactic.
| Name | Required | Description | Default |
|---|---|---|---|
| tactic | No | Filter by ATT&CK tactic (e.g. "initial-access") |
Output Schema
| Name | Required | Description |
|---|---|---|
| tactics | No | |
| top_techniques | No | |
| total_techniques | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well covered. The description adds the 'coverage across the platform' aggregation scope and the tactic-filtering behavior, which adds value beyond annotations. However, it doesn't describe what 'coverage' means (e.g., counts, percentages, technique statuses) or return shape, though an output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler. Every word earns its place: the verb, the resource, the platform scope, and the optional filter. Highly front-loaded with the core purpose in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple filtered read with strong annotations (read-only, idempotent) and a full schema (1 param at 100% coverage) plus an output schema, the description is reasonably complete. 'Coverage' could be more explicitly defined in terms of what the agent will see, but the output schema presumably fills that gap. It doesn't differentiate from the related get_mitre_gap_analysis tool, which is a minor completeness gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the tactic parameter is fully documented in the schema with an example ('initial-access'). The description adds the 'optionally filter' semantic, confirming the parameter is non-required, which matches the 0 required parameter count. Baseline 3 is appropriate since the schema already covers parameter meaning fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Get') and resource ('MITRE ATT&CK coverage across the platform'), which is distinct from siblings like get_mitre_technique (specific technique) and get_mitre_gap_analysis (gap analysis). The 'across the platform' scope helps differentiate it, though it doesn't explicitly name alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Optionally filter by tactic' which gives some context, but provides no guidance on when to use this vs get_mitre_technique, get_mitre_gap_analysis, or predict_mitre_transitions, which are all MITRE-related sibling tools. No when-not-to-use guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_mitre_gap_analysisMITRE Gap AnalysisARead-onlyIdempotent
Prioritized list of MITRE ATT&CK techniques with the weakest detection coverage (detection debt), ranked by debt_score = attributed threats / (1 + detection rules mapping the technique or its parent), scaled by exploitability (max EPSS / KEV of the CVEs its threats weaponize) and rarity. Higher = more exposure with less rule coverage. Filter by tactic (spelling-insensitive: "execution", "Execution" and "Execution (ICS)" all match) and cap with limit; summary.gaps/coverage_pct describe the FILTERED corpus, not the returned page.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max techniques (default 20, max 100). Rows come back debt_score-descending, so limit=N is the top-N worst. | |
| tactic | No | Filter to one ATT&CK tactic (e.g. "execution", "defense-evasion", "command-and-control"). An unmatched value returns summary.available_tactics. |
Output Schema
| Name | Required | Description |
|---|---|---|
| summary | No | |
| techniques | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, idempotent, and non-destructive behavior. The description adds valuable details beyond that: the ranking formula, that tactic matching is spelling-insensitive, and that summary.gaps/coverage_pct describe the filtered corpus rather than the returned page, which is an important caveat.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized for the subtleties involved: it defines the ranking, the filtering behavior, and the summary caveat in two sentences. It is a bit dense with the formula, but every component is useful rather than redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema and only two optional parameters, the description covers purpose, ranking, filtering, limit semantics, edge-case behavior for unmatched tactics, and a confusing summary nuance. It could be even stronger if it explicitly contrasted this tool with get_mitre_coverage or get_technique_rules, but it is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema itself documents both parameters. The description still adds value by clarifying that tactic filtering is case/spelling-insensitive, including variants like 'Execution (ICS)', and that limit=N-N maps directly to debt_score-descending top N rows.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool returns a prioritized list of MITRE ATT&CK techniques with the weakest detection coverage, ranked by debt_score. It goes beyond the title by defining what gap analysis means here and clearly distinguishes this from sibling coverage/technique tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear operational guidance: filter by tactic, use limit as a cap, and understand that limit=N yields the top-N worst. It does not explicitly name alternative tools or state when not to use this, but it gives solid context for normal invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_mitre_techniqueMITRE TechniqueARead-onlyIdempotent
Get details for a specific MITRE ATT&CK technique by ID (e.g. T1059 or T1059.001): authoritative name, tactics, matrix, revocation status, mitigations, detection data sources, and the corpus threats using it. The threat list is paged — a heavily-used technique attaches hundreds of threats, so pass include_threats=false for the definition alone (a few KB), or limit/offset to page. threat_count always reports the true total.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max threats to return (default 50, max 500) | |
| offset | No | Threat-list row offset for paging (default 0) | |
| technique_id | Yes | Technique ID (e.g. T1059 or T1059.001) | |
| include_threats | No | Set false to return the technique definition WITHOUT the threat list (default true). Use this when you only need the name/tactic/mitigations. |
Output Schema
| Name | Required | Description |
|---|---|---|
| matrix | No | |
| source | No | 'attack_catalog' (authoritative) | 'threat_mitre_fallback' | 'unknown'. |
| tactic | No | |
| revoked | No | |
| tactics | No | |
| threats | No | |
| technique | No | |
| deprecated | No | |
| revoked_by | No | Successor technique id when this one was retired — query that id instead. |
| detail_hint | No | |
| mitigations | No | |
| data_sources | No | |
| technique_id | Yes | |
| threat_count | No | TOTAL threats using this technique — compare against threats_returned to see whether the list is a page. |
| threats_offset | No | |
| threats_omitted | No | Present and true when include_threats=false suppressed the list. |
| parent_technique | No | |
| threats_has_more | No | |
| threats_returned | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, but the description meaningfully exceeds that: it warns about the potentially huge threat list on a heavily-used technique, recommends include_threats=false for a few KB response, explains paging via limit/offset, and clarifies that threat_count always reports the true total. This alerts the agent to payload-size and performance behavior not visible in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The first sentence states the core operation and full return-listing; the second covers paging/performance trade-offs. Every clause earns its place, and the description is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and annotations cover the safety profile, the description itself contains everything needed for a correct invocation: required ID format, what fields come back, the optional payload-size switch, pagination controls, and the meaning of threat_count. It leaves no practical gap for an agent selecting or calling this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers all four parameters at 100% with helpful descriptions (defaults, max, 'underthehood'). The description goes beyond by explaining how include_threats=false compared to to page 'the low definition alone (a few KB)' rather than relying on names. That added rationale and the threat_count guarantee lifts it above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Get details for a specific MITRE ATT&CK technique by ID (e.g. T1059 or T1059.001)' which is a precise verb + resource + scope. It enumerates the exact fields returned, which clearly differentiates this lookup tool from the many MITRE-adjacent siblings (coverage, transitions, rules, attack flow).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly identifies the primary use case and gives strong in-tool guidance: how to request just the definition via include_threats=false, how to page the threat list, and what behavior to expect from threat_count. It does not explicitly contrast against alternatives or name when-not-to-use, but no obvious sibling overlaps directly, so explicit exclusions are less critical.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_osintGet OSINT CorroborationARead-onlyIdempotent
Community corroboration for a threat or an indicator from the TL_OSINT_Scan layer (tweetfeed.live, CC0). Given threat_id, returns the matched community tags, the corroborated indicator count, and whether the community saw an indicator BEFORE our report. Given ioc_value, returns sightings, reporters, tags and every linked threat. Community-sourced and heavily concentrated (~73% of recent submissions come from a single reporter) — treat as corroborating evidence, never as authoritative attribution.
| Name | Required | Description | Default |
|---|---|---|---|
| ioc_value | No | Exact indicator (IP, domain, URL, MD5 or SHA256). Returns the community lookup + our linked threats. | |
| threat_id | No | Threat ID (e.g. TL-2026-1531). Returns the per-threat corroboration block. |
Output Schema
| Name | Required | Description |
|---|---|---|
| value | No | Present on the per-IOC shape (ioc_value input). |
| scanned | No | |
| lead_days | No | Days the community saw an indicator before our report. |
| reporters | No | |
| threat_id | No | Present on the per-threat shape. |
| threat_ids | No | |
| corroborated | No | |
| matched_tags | No | |
| indicator_count | No | |
| community_seen_before_report | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description discloses the data source (tweetfeed.live, CC0), a concentrated submission pattern (~73% from a single reporter), and explicitly warns to treat results as corroborating evidence, never as authoritative attribution. This is valuable context that annotations do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: purpose, per-parameter behavior, and a reliability caveat. It is front-loaded with the core function and contains no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (2 parameters, output schema provided), the description covers all necessary aspects: both usage modes, data provenance, and a critical reliability caveat. The output schema handles return value structure, so no gap exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds return-field details beyond the schema's brief parameter descriptions: for threat_id it lists matched community tags, corroborated indicator count, and the BEFORE report flag; for ioc_value it lists sightings, reporters, tags, and linked threats. This significantly enriches the meaning of each parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool provides 'Community corroboration for a threat or an indicator from the TL_OSINT_Scan layer', with specific outputs for threat_id and ioc_value. This distinguishes it from sibling tools like get_osint_trends and get_ioc_intelligence by focusing on corroboration from a specific data source.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use the tool (when community corroboration is needed) and describes behavior for each parameter. It does not explicitly name alternatives or exclusions, but the context is clear enough for an agent to select it appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_osint_trendsCommunity OSINT TrendsARead-onlyIdempotent
What the security community is surging on right now (tweetfeed.live, CC0), joined against our own corpus coverage: trending tags with movement, TLD distribution, novelty, top producers, daily volume — plus corpus (how much of our corpus the community corroborates) and early_warning (the lead-time distribution). The coverage-gap and lead-time read; the corpus join exists nowhere else. Keyed on community TAGS, not malware family (populated on <1% of upstream rows).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| tlds | No | |
| daily | No | |
| caveat | No | |
| corpus | No | |
| movers | No | |
| totals | No | |
| novelty | No | |
| producers | No | |
| generated_at | No | |
| early_warning | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With strong annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false), the safety profile is fully covered by structured data. The description adds meaningful behavioral context beyond that: the keying on community tags rather than malware family, the data source provenance (tweetfeed.live, CC0), and the population caveat (<1% of upstream rows). This gives the agent a realistic expectation of data sparsity that annotations can't convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact given the breadth of data dimensions it names, and the critical distinguishing detail (corpus join, tag keying) is front-loaded near the start. The parenthetical sourcing note is efficient. It could save a few words on enumerating every data dimension, but it's an appropriately dense single block.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a read-only aggregate view with an output schema present, so the description doesn't need to enumerate return fields. The description explains the data's source, its unique value proposition, and important caveats about tag population. For a no-parameter read tool, this level of contextual depth is adequate and complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and 100% schema coverage (empty schema), so there are no parameter semantics to document. The description instead provides rich context about the returned data dimensions (corpus coverage, early warning lead-time distribution), which substitutes for the parameter guidance that would normally be needed. With 0 params, the baseline is 4 per rubric.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a community-driven trends view ('what the security community is surging on'), with specific data dimensions named (trending tags, TLD distribution, novelty, top producers, daily volume). The verb 'get' plus the resource 'trends' is specific, and the niche framing ('joined against our own corpus coverage,' 'exists nowhere else') helps differentiate it from siblings like get_platform_stats or get_landscape_briefing. However, the distinction from platform/landscape stats siblings is implicit rather than explicitly contrasted.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong contextual guidance on what makes this tool unique ('the corpus join exists nowhere else') and clarifies important semantics ('Keyed on community TAGS, not malware family'). It tells the agent this covers a specific niche that other tools don't. However, it doesn't explicitly say when NOT to use it or name alternative tools for users wanting coverage-gap or lead-time reads in isolation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pivotal_entitiesPivotal EntitiesARead-onlyIdempotent
The hubs and bridges of the intelligence graph ranked by weighted degree and approximate betweenness — where a single detection buys the most coverage. NOTE: betweenness is an ego-bridge heuristic, not exact Brandes; the response says so in note. Do not present it as exact betweenness.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 25, max 100. | |
| node_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| note | No | States that betweenness is an ego-bridge approximation, not exact Brandes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable caveats beyond annotations: it explicitly warns that betweenness is an 'ego-bridge heuristic, not exact Brandes' and instructs not to present results as exact betweenness, noting the response carries this in `note`. This is genuine behavioral disclosure well beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, efficient and front-loaded. The first sentence establishes what the tool returns and the ranking; the second delivers the critical caveat about betweenness. No wasted words. It loses one point because the caveat is placed at the end, slightly reducing the immediate clarity of the safety-critical warning, though the structure is overall tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema (so return values need no description), two simple parameters, and rich annotations covering read-only/idempotent/destructive profile. Given this context, the description adequately explains the ranking semantics and the heuristic caveat. It's complete for a read-only ranked-list tool; a minor gap is not explaining the node_type filtering behavior in the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50%, meaning the limit parameter is described (default 25, max 100) in the schema while node_type is described only via its enum values. The description doesn't add parameter-level detail beyond the schema — it doesn't explain how node_type filters results or how limit interacts with ranking. With 50% coverage, the description carries some compensation burden but mostly remains silent on parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves 'the hubs and bridges of the intelligence graph' ranked by 'weighted degree and approximate betweenness.' It uses a specific verb (get) plus a well-defined resource (pivotal entities = hubs/bridges) with explicit ranking criteria. This meaningfully distinguishes it from siblings like get_infrastructure_pivots or get_correlation_path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: to identify high-coverage nodes in the intelligence graph where a detection buys maximum coverage. It frames the 'when to use' clearly ('where a single detection buys the most coverage'), but it does not explicitly say when NOT to use it or name alternative tools for specific scenarios. The node_type parameter suggests filtering by entity type, but the description doesn't guide which type to pick.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_platform_statsPlatform StatsARead-onlyIdempotent
Get aggregate platform statistics: threat, detection, IOC, MITRE technique, and actor counts.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| top_actors | No | |
| total_iocs | No | |
| total_ttps | No | |
| by_category | No | |
| by_severity | No | |
| total_actors | No | |
| total_threats | No | |
| top_techniques | No | |
| total_detections | No | |
| total_correlations | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well-covered by structured data. The description adds the scope of what counts are returned (threat, detection, IOC, MITRE, actor) but doesn't disclose aggregate semantics like whether counts are deduplicated, time-bounded, or filtered, which would add value beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that enumerates the five data categories with zero wasted words. It front-loads the key action term and is perfectly sized for a zero-parameter aggregate endpoint.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 0 parameters and annotations declaring it read-only, idempotent, and non-destructive, the description covers the primary behavioral aspects adequately. An output schema exists to explain return structure. However, the description could note whether counts are global/total versus time-windowed, which would improve completeness for a stats endpoint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has 0 parameters and schema coverage is 100%, so there are no parameter semantics to explain. The description appropriately focuses on what data the tool returns rather than parameter behavior, which is the correct compensation given the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource ('Get aggregate platform statistics') and enumerates the specific data categories included (threat, detection, IOC, MITRE technique, actor counts), clarifying scope. However, it doesn't explicitly distinguish from sibling tools like get_enrichment_overview or get_landscape_briefing, which could overlap conceptually.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this is a high-level overview tool, but it doesn't state when to use it versus sibling alternatives like get_enrichment_overview or get_landscape_briefing. There's no explicit exclusion or alternative guidance, making usage context clear-ish but not differentiated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recent_threatsRecent ThreatsARead-onlyIdempotent
List the most recently published threats. Paginated: pass limit (default 15, max 100) and offset to page through older threats; the result includes has_more and an opaque next_cursor (reusable as offset/cursor).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results (default 15, max 100) | |
| cursor | No | Opaque pagination cursor (next_cursor from a prior result). Decoded to an offset; ignored when offset is given. | |
| offset | No | Row offset for pagination (default 0). Or pass cursor from a prior result. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| total | No | Total matching rows, when the handler reports one. |
| has_more | No | True when another page may exist. |
| next_cursor | No | Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, covering the safety profile. The description adds meaningful value by explaining pagination behavior — that next_cursor is opaque, reusable as offset/cursor, and that offset/cursor interplay ('ignored when offset is given') — which goes beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero wasted words. The description front-loads the core purpose in the first clause, then packs the pagination contract concisely. Every phrase ('opaque', 'reusable as offset/cursor') earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a valid output schema, high schema coverage, and strong annotations, the description is nearly complete. It explains the essential pagination contract clearly. The only minor gap is not naming alternatives explicitly, but for a paginated list tool this is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters are fully documented in the schema. The description adds value by clarifying the relationship between cursor and offset (cursor decoded to offset, ignored when offset given) and describing the has_more/next_cursor return format, which compensates meaningfully beyond the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb+resource ('List the most recently published threats') and adds the pagination scope detail. It distinguishes from siblings like get_threat (single), search_threats (search filter), and get_similar_threats (similarity) by emphasizing 'recently published' ordering.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description and parameter docs explain pagination mechanics (limit, offset, cursor, has_more, next_cursor). It doesn't explicitly state when to prefer this over search_threats vs get_threat, but the 'most recently published' framing and pagination semantics give clear usage context without naming alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_roadmapGet RoadmapARead-onlyIdempotent
Get the Threadlinqs Intelligence platform roadmap: completed, in_progress and ideas (planned), with counts, generated_at and as_of. WARNING: this table is hand-maintained and has not been updated since Feb 2026 — the response carries stale_days and a warning, and several items still marked "planned" have since shipped. Do not report an item as unbuilt on this basis; confirm with get_started (live tool catalog), get_platform_stats or get_engine_status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | No | Last date the roadmap table itself was edited. |
| ideas | No | |
| stale | No | |
| counts | No | |
| warning | No | Present when stale; says the statuses are unreconciled. |
| completed | No | |
| stale_days | No | |
| in_progress | No | |
| generated_at | No | When this response was produced. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint true, and the description adds meaningful behavioral context beyond them: the data is stale, a stale_days field and warning are returned, and several planned items have already shipped. This transparency is critical to accurate agent behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, with the core resource and fields stated first and the important staleness warning placed immediately after. Every sentence adds essential information, with no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read-only tool with an output schema and rich annotations, this description fully covers what an agent need aware of. It explains the data source, staleness, response warning, and which sibling tools to use for authoritative status checks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no parameters, so the schema provides no parameter semantics to clarify. The description adds value by listing the output fields such as completed, in_progress, ideas, counts, generated_at, as_of, and stale_days, which supports expectation-setting for the response.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the exact resource and verb: retrieving the Threadlinqs Intelligence platform roadmap. It enumerates the statuses and fields returned, so an agent knows precisely what information the tool provides and can distinguish it from other catalog/status tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly warns that the roadmap is hand-maintained and stale, and instructs the agent to confirm current build status with get_started, get_platform_stats, or get_engine_status instead. This gives clear when-not-to-use guidance and names specific alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_similar_threatsSimilar ThreatsARead-onlyIdempotent
Threats similar to a given threat, with the EVIDENCE behind each link: per-channel score breakdown, which signal dominates, the concrete shared techniques / IOCs / CVEs, and quality flags for stale or high-confidence-low-evidence links. Use explain_correlation for a full decomposition of one specific pair.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Source threat ID (e.g. TL-2026-0042) | |
| limit | No | Max results (default 10, max 20 — the handler caps here). |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | |
| count | No | |
| counts | No | |
| similar | No | |
| source_threat_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior. The description adds value by revealing return behavior: evidence per link, score breakdown, dominant signal, shared indicators, and quality flags for stale or high-confidence-low-evidence links. This gives an agent useful expectations beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense, front-loaded sentences. The first sentence immediately states what the tool returns and the key evidence qualities; the second routes to the related correlation tool. No filler or repeated annotation content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, idempotent, two-parameter tool with a complete schema and an output schema, the description sufficiently explains the purpose and result shape. It also tells the agent where to go for the deeper follow-up task, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents both parameters fully, including an example ID and the limit cap. The description adds no new parameter-level meaning, but because coverage is 100%, the schema carries the burden and the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific resource (threats similar to a given threat) and explains what the results contain: evidence, per-channel score breakdown, dominant signal, shared techniques/IOCs/CVEs, and quality flags. It also names explain_correlation as a related but distinct tool, which prevents confusion with sibling tools such as get_flow_similar_threats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies this tool is for finding and comparing multiple similar threats, and explicitly says to use explain_correlation when you need a full decomposition of one specific pair. It does not enumerate every sibling alternative or say when not to use it, but the primary alternative is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_startedGet StartedARead-onlyIdempotent
Start here. Returns the Threadlinqs Intelligence tool catalog, categories, tiering, and usage guidance. No API call — read this before using other tools.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| tools | Yes | |
| server | No | |
| exports | No | |
| tiering | No | |
| resources | No | |
| categories | No | |
| instructions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safe read-only nature is fully covered by structured data. The description adds modest value by noting 'No API call' — implying it's offline/local — but lacks detail on what the return payload looks like, size of the catalog, or how much guidance is included. With strong annotations, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with zero waste. The 'Start here' opener front-loads the critical instruction, followed by a clear description of return contents and the 'read before using' directive. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 0-parameter, read-only catalog tool with an output schema present and strong annotations, the description is complete. It covers what's returned, the prerequisite guidance, and the non-API nature. It doesn't detail output size or categories, but the presence of an output schema lowers that burden. It's sufficient for an agent to correctly select and invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0 parameters and 100% schema coverage, there are no params to document. The description appropriately focuses on what the call returns rather than parameter constraints. The baseline for a 0-parameter tool is 4, and the description adequately conveys the tool's contract without needing parameter explanations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Returns the Threadlinqs Intelligence tool catalog, categories, tiering, and usage guidance.' It uses specific verbs and resources, and the 'Start here' framing distinguishes it as an onboarding tool. However, it could more explicitly separate itself from sibling onboarding tools like get_roadmap, though the catalog/usage-guidance scope is fairly distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'read this before using other tools,' providing clear when-to-use guidance. It also notes 'No API call,' which signals it's a local/metadata read. It doesn't explicitly name exclusion criteria vs alternatives, but the 'start here' instruction effectively orients the agent toward correct usage before consulting siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_technique_rulesTechnique Co-occurrence RulesARead-onlyIdempotent
MITRE ATT&CK technique PAIRS mined from the corpus with support, confidence and lift — which techniques travel together far above chance. Each rule carries both technique ids AND their ATT&CK names (technique_a_name / technique_b_name), so a rule is readable without a follow-up lookup. Complements predict_mitre_transitions exactly: that answers sequence (what follows what), this answers co-occurrence (what appears alongside what). Rules come back lift-descending; summary.total_rules reports how many exist in total, so has_more tells you whether the tail was cut. Note minSupport 0.02 — a pair must appear in ~2% of threats to be mined at all, so rare-technique pairs are structurally absent rather than uncorrelated.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 50, max 100. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rules | Yes | |
| summary | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description additionally reveals the minSupport cutoff of 0.02, the lift-descending sort order, the presence of summary.total_rules and has_more for pagination, and that names are included to reduce follow-up lookups. This goes well beyond the annotations with material behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries distinct and necessary information: core output, adjacent distinction, ordering/pagination, and interpretation caveat. It is front-loaded with the main purpose and remains compact without redundant wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has one optional parameter, no destructive behavior, rich annotations, and an output schema. The description still adds crucial output semantics around total rules, has_more, sorting, and the minSupport miners, so an agent can select it and interpret its result without uncovered surprises.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter, limit, and the schema already covers it with default and max values at 100% coverage. The description does not need to add parameter semantics, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Describes exactly what the tool provides: MITRE ATT&CK technique pairs mined from the corpus with support, confidence, and lift. It clearly describes the co-occurrence focus and explicitly distinguishes it from the sequence-focused predict_mitre_transitions tool, making the resource and intent unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the only sensible sibling alternative, predict_mitre_transitions, and explains the selection criterion: sequence versus co-occurrence. It also warns about the minSupport threshold, so an agent knows rare-pair results will be absent by design rather than anomalous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threatGet ThreatARead-onlyIdempotent
Get the detail for a single threat by its ID (e.g. TL-2026-0042): overview, attribution, MITRE techniques, IOCs, the detection roster, timeline, targets and tags. RETRIEVABLE IN PARTS — pass sections to choose what comes back; the response echoes _sections telling you what was returned and what was omitted. By default detection RULE BODIES (SPL/KQL/Sigma) are omitted — they are ~40% of a heavy dossier and have dedicated tools (export_detection / get_detection_detail) — and description is trimmed to 1500 chars with description_chars disclosing the true length. Pass sections="all" and max_description=-1 for the complete record. For malware families, tools, sectors/regions, OS and campaigns, call get_threat_enrichment.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Threat ID (e.g. TL-2026-0042) | |
| sections | No | CSV of sections to return. Any of: overview, attribution, mitre, iocs, detections (WITH rule bodies), detections_meta (roster only, the default), timeline, tags, targets, remediation, references (full bibliography), references_compact (ranked primary-first + corroboration summary, in the default), similar, updates, osint, flow, entities — or "all", or "row" (exclusive: a ~500-byte identity row plus section counts). Default: overview,attribution,mitre,iocs,detections_meta,timeline,tags,targets,similar,flow,osint,references_compact | |
| max_description | No | Char budget for the narrative description. Default 1500; 0 drops it; -1 returns it whole. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Threat ID (TL-YYYY-NNNN). |
| iocs | No | |
| tags | No | |
| osint | No | Community-OSINT summary; null below Red tier or when unscanned. |
| title | No | |
| status | No | |
| summary | No | |
| category | No | |
| severity | No | |
| _sections | No | |
| created_at | No | |
| detections | No | |
| references | No | Full bibliography. Present only under sections=references or sections=all. |
| updated_at | No | |
| attribution | No | |
| description | No | |
| identifiers | No | |
| mitre_attack | No | |
| description_chars | No | True length of description when it was trimmed to max_description. |
| references_compact | No | Ranked primary-first, capped at 8. Present in the DEFAULT projection and in both bundles. |
| references_summary | No | |
| description_truncated | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds materially beyond that: the response echoes `_sections` to tell the caller what was returned/omitted, detection RULE BODIES are omitted by default (~40% payload), `description` is trimmed to 1500 chars with `description_chars` disclosing the true length, and the escape hatch of sections="all" + max_description=-1 for the full record. That is rich, non-redundant behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A dense but well-structured description: first sentence establishes the core purpose, then the behavioral flags (retrievable in parts, chunked payload, omitted rule bodies), then the escape hatch, then the routing to the enrichment sibling. Every sentence earns its place and the most decision-relevant facts are front-loaded. Not a word of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with an output schema, return values need no explanation, and the description covers the remaining behavioral gotchas: default sections, payload size implications, how to read the response via _sections, and how to get the full dossier. An agent has everything needed to invoke this tool correctly and to know precisely how to adjust behavior for different use cases. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 — the schema already documents id, sections, and max_description including literal defaults. The description adds real value on top by explaining WHY the trim exists (payload size), that max_description=-1 returns the whole record, and the detections vs detections_meta distinction in context. It's genuine added meaning, but the schema carries most of the parameter documentation burden, so 4 rather than 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Get the detail') targeting a single threat by ID, and enumerates the content: overview, attribution, MITRE techniques, IOCs, detection roster, timeline, targets, tags. It explicitly differentiates itself from siblings by pointing to get_threat_enrichment for malware/tool/sector/OS/campaign data and mentioning export_detection/get_detection_detail as the tools that handle rule bodies, so an agent can distinguish it from search_threats, get_recent_threats, and related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit routing guidance: detection rule bodies are omitted by default because they are ~40% of a heavy dossier and have dedicated tools (export_detection / get_detection_detail). It also states exactly when to use get_threat_enrichment ('For malware families, tools, sectors/regions, OS and campaigns, call...'). This is explicit when-to/not-to guidance with named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threat_bundleGet Threat BundleARead-onlyIdempotent
One-shot dossier for a threat: threat detail plus its simulations and pipeline transcripts (include="summary" returns just the threat). Fewer round-trips than get_threat + get_threat_simulations + get_threat_transcripts separately. The threat is the same bounded projection get_threat returns by default — call get_threat(id, sections="all") for the unabridged record.
| Name | Required | Description | Default |
|---|---|---|---|
| include | No | "full" (default) bundles simulations + transcripts; "summary" returns just the threat | |
| threat_id | Yes | Threat ID (e.g. TL-2026-0042) | |
| simulation_limit | No | Playbooks to embed, 1-20 (default 3). Each carries full command text; raise only if you need more than the newest few. |
Output Schema
| Name | Required | Description |
|---|---|---|
| threat | Yes | |
| simulations | No | |
| transcripts | No | Omitted entirely when include='summary'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnly, idempotent, non-destructive behavior. The description adds value beyond these annotations by explaining the bounded nature of the returned threat projection, the effect of include='summary', and that it bundles multiple data sources into one response. This is transparent about behavior without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the first defines the bundle, the second explains its round-trip advantage, and the third clarifies the bounded nature and points to an alternative. It is front-loaded with the core purpose and avoids redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only bundled tool with a full output schema and complete parameter schemas, this description covers all necessary agent guidance: what the bundle includes, how to narrow the response, when to use alternatives, and how the bundled 'threat' compares to get_threat's default projection. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds useful content beyond the schema: include='summary' yields just the threat, simulation_limit embeds full command text, and the warning to raise the limit only when needing more than the newest few playbooks. These clarifications make the parameter semantics easier to apply correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'One-shot dossier for a threat: threat detail plus its simulations and pipeline transcripts.' It clearly distinguishes itself from the component calls it bundles (get_threat + get_threat_simulations + get_threat_transcripts), and clarifies that include='summary' returns just the threat.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when this tool is preferable ('Fewer round-trips than get_threat + get_threat_simulations + get_threat_transcripts separately') and names the alternative for an uncompressed record ('call get_threat(id, sections="all") for the unabridged record'). This gives an agent a concrete decision rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threat_enrichmentThreat EnrichmentARead-onlyIdempotent
Reference-grounded enrichment for one threat by ID: the malware families and tools used, targeted sectors/regions, affected operating systems, named campaigns, AI/ML (ATLAS) techniques, and per-technique mitigations + detection data sources. Complements get_threat (overview/MITRE/IOCs/detections) — call this for the "what malware/tools were used and who was targeted" view. Read coverage before acting on an empty array: grounded = the normalised association tables, threat_record = fell back to the threat's own target_sectors/target_regions, unmapped = NOT MAPPED, which is not the same as not targeted.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Threat ID (e.g. TL-2026-0042) |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| atlas | No | |
| tools | No | |
| malware | No | |
| regions | No | |
| sectors | No | |
| coverage | No | |
| campaigns | No | |
| operating_systems | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, so the safety burden is covered. The description adds valuable behavioral nuance beyond annotations: the meaning of 'grounded' vs 'threat_record' and the critical 'unmapped' warning that 'not mapplied ≠ not target'. This is genuinely useful, though some runtime details (e.g., error handling of invalid ID) could still be expanded.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences: the first structures the resource, the second gives the sibling-guidance, and the third gives an important caveat about the 'coverage' field. Each sentence carries weight without going too long; the description is dense but every inline list member affects what the agent needs to know about the response.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-ID, read-only, idempotent tool with an output schema present, the description covers the whole decision context: when to call it, what it returns, how to interpret coverage values, and the false-negative trap of 'unapped'. It grounds the awkward "empty array" case up front, giving an agent everything needed to make a correct call and correct interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, and the schema already says the id is a Threat ID with an example. The description merely repeats that it's by ID and adds no additional parameter syntax, constraints, or format. Therefore a baseline 3 is appropriate since the schema carries the parameter-semantic burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific resource and verb: 'Reference-grounded enrichment for one threat by ID', then enumerates exactly what is returned (malware families, tools, sectors, OS, campaigns, ATLAS techniques, mitigations). It also clearly separates this tool from get_threat by naming the difference between its full-fields view and get_threat's overview/MITRE/IOCs/detections. This leaves no ambiguity about what the tool does or how it differs from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to call this tool: 'call this for the "what malware/tools were used and who was targeted" view', and names get_threatest as the complement. It also gives conditional guidance for reading the 'coverage' field, which is a direct interpretation rule that prevents misreading empty arrays.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threat_hunting_bundleThreat Hunting BundleARead-onlyIdempotent
Flagship one-call hunting dossier for a threat: threat detail + similar threats + simulations + infrastructure pivots, composed server-side. Best single tool to scope a hunt around one threat. Every section is bounded so the bundle fits in one response — raise simulation_limit / pivot_limit, or call get_infrastructure_pivots and get_threat directly, when you need the full lists.
| Name | Required | Description | Default |
|---|---|---|---|
| shape | No | "v1" (default, unchanged nested envelope) | "canonical" (flat, stably-named, SMALLER — recommended for programmatic consumers) | "both". In canonical: technique ids are a top-level `ttps` array, sectors/regions use ONE spelling, and every array key is ALWAYS an array (never null, never an object). In v1, `similar_threats` and `infrastructure_pivots` are handler envelopes (objects) while `threat.similar_threats` is a flat array — if you are writing a parser, use canonical. | |
| threat_id | Yes | Threat ID (e.g. TL-2026-0042) | |
| pivot_limit | No | Infrastructure pivots to embed, 1-200 (default 25). One threat can carry 150+; get_infrastructure_pivots returns the full set. | |
| simulation_limit | No | Playbooks to embed, 1-20 (default 3). |
Output Schema
| Name | Required | Description |
|---|---|---|
| iocs | No | canonical: FLAT array. (In v1 this is an object keyed by category under threat.iocs.) |
| ttps | No | Canonical MITRE technique ids, present in BOTH shapes. |
| _shape | No | |
| counts | No | canonical: a denominator for every array key. |
| threat | No | |
| regions | No | |
| sectors | No | |
| _envelope | No | Shape manifest — announces that shape="canonical" exists. |
| canonical | No | Present only under shape="both". |
| threat_id | No | |
| simulations | No | |
| ttp_details | No | |
| similar_threats | No | v1: handler envelope {source_threat_id, count, similar[]} — an OBJECT, not an array. |
| infrastructure_pivots | No | v1: handler envelope {threat_id, infrastructure_pivots[], coverage{}} — an OBJECT. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, and non-destructive behavior. The description adds genuinely useful behavioral context: the bundle is composed server-side, every section is bounded so the response fits in one call, and limits can be raised or fallback tools used. It does not mention latency or payload-size expectations, but it goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences; the first explains composition, the second gives the primary use case, and the third explains limits and when to use alternatives. Every sentence earns its place, and the description is front-loaded with the most important information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-call bundle tool with an output schema and 100% parameter schema coverage, the description covers what the bundle contains, why and when to use it, how to control response size, and what to call instead for full lists. Nothing needed for correct selection or invocation is left out.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the parameters are already well documented. The description adds extra value by explicitly tying simulation_limit and pivot_limit to the bounded-list behavior and by naming the fallback tools to get complete lists. This is more than the baseline, though each parameter's precise meaning still comes from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: a one-call hunting dossier that composes threat detail, similar threats, simulations, and infrastructure pivots server-side. It clearly differentiates from get_threat and get_infrastructure_pivots via the fallback note, but it does not explicitly distinguish from the closely titled sibling get_threat_bundle, so it misses full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says this is the best single tool to scope a hunt around one threat and gives concrete when-not usage: raise simulation_limit/pivot_limit, or call get_infrastructure_pivots and get_threat directly when full lists are needed. This is clear, actionable selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threat_levelThreat LevelARead-onlyIdempotent
Get the computed current threat-landscape level (a 0–25 rating of overall posture).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| max | No | |
| level | Yes | |
| score | Yes | |
| criteria | No | |
| threats_observed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the safety profile is covered. The description adds that the value is 'computed' and 'current', implying it's a derived metric. Beyond that, it doesn't disclose behavior like caching, refresh semantics, or what 'computed' entails, though this is minor for a read-only getter.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that efficiently states the purpose and output format with zero waste. It includes the meaningful detail of the 0-25 range to set expectations. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is an output schema present, so return-value documentation is covered. For a zero-parameter read-only getter with good annotations and a defined output schema, the description is reasonably complete. It could arguably add what 'threat-landscape' encompasses, but the output schema likely covers the structure. The single-sentence description is adequate for this tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, making parameter semantics largely moot. With schema description coverage at 100% and no parameters, the baseline of 4 applies. The description goes slightly beyond by explaining the output is a 0-25 rating, which clarifies what the returned value represents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb+resource: 'Get the computed current threat-landscape level'. It even clarifies the output is a 0-25 rating of overall posture. However, among many sibling tools (get_landscape_briefing, get_threat_level vs get_recent_threats, etc.), it doesn't explicitly differentiate from alternatives beyond the narrow scope of 'current' stated level.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage via 'computed current threat-landscape level' — this is a snapshot of present posture, distinct from briefing-style or historical tools. However, there's no explicit when-to-use or when-not-to-use guidance, nor naming of alternative tools for comparison, which is notable given 70+ siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threat_simulationsThreat SimulationsARead-onlyIdempotent
DEPRECATED (generation stopped 2026-08-03; ~5,362 archived rows still served, no new ones are produced) — the response carries deprecated:true and the caveat inline. Adversary-emulation playbooks attached to a threat. Most were synthetic-telemetry generators against local mocks rather than real execution, so they could not trigger the platform's own detections. One threat's playbooks can run 30 KB+ of command text: narrow with platform (see available_platforms) and limit. An empty result carries a reason distinguishing "this threat never had any" from "none for that platform". Prefer get_attack_flow, which returns the analyst-authored causal DAG that replaced them.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max playbooks to return (max 50). Omit for all — bodies are large. | |
| platform | No | Return only this platform: windows, linux, python (also aws, macos, multi on a few rows). Omit for all. | |
| threat_id | Yes | Threat ID (e.g. TL-2026-0042) |
Output Schema
| Name | Required | Description |
|---|---|---|
| caveat | No | Why these do not prove your detections fire. |
| reason | No | Present only on an empty result: no_simulations_for_threat | no_simulations_for_platform. |
| matched | No | |
| returned | No | |
| platforms | No | |
| threat_id | Yes | |
| truncated | No | |
| deprecated | No | |
| simulations | No | |
| total_simulations | No | All archived playbooks for this threat, before platform/limit. |
| generation_stopped | No | Date generation stopped (2026-08-03). |
| available_platforms | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint, idempotentHint), the description discloses substantive data-behavior nuances: generation stopped, only archived rows remain, playbooks are synthetic and won't trigger detections, and an empty result distinguishes 'this threat never had any' from 'none for that platform'. That is enrichment annotations do not capture.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the most important arc (DEPRECATED) and elevides every detail: status, data volume, quality caveat, performance trigger, response semantics, and replacement., the one-sentence structure is effectively a compact CLI-style summary with no inerous commentary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only getter with a schema and output schema already present, the description is complete—youth provide and exact dark context, a response caveat (§empty reason), size/vacceptility constraint, and a migration path. There is nothing an agent would need to know to safely invoke or interpret this tool that is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers 100% of parameter descriptions. The description adds justification for using limit/platform ('30 KB+ of command text'), but does not explain new parameter semantics—it reinforces rather than defines. Baseline of 3 applies because the schema handles the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the exact resource ('adversary-emulation playbooks attached to a threat') and clearly identifies its scope and relationship. It also differentiates from the replacement tool get_attack_flow, so an agent can tell this tool apart from relevant siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly marks the tool as deprecated, names the preferred alternative (get_attack_flow), and advises how to narrow results when they could be huge ('narrow with platform (see available_platforms) and limit'). This-level of when-to-use and when-not-to-use guidance is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threat_transcriptsGet Threat TranscriptsARead-onlyIdempotent
Get the PIPELINE PROVENANCE record for a threat — how its profile was produced, not analysis of the threat itself. Returns the 7 pipeline phases (HUNT/RESEARCH/SIMULATION/DETECT/PUBLISH/CORRELATION/TRANSCRIPT) with per-phase timing, the quality gates and their PASS/FAIL metrics (tag/technique/IOC/reference counts), an overall quality score, the inter-agent handoff log, and correlation_highlights (related threat ids and the high-frequency IOCs that linked them). The handoff messages are routing stubs and file pointers, NOT analyst prose — do not expect written reasoning about the adversary. Use this to judge how thoroughly a threat was worked and to find its related-threat/IOC leads; use get_threat or get_threat_enrichment for the analysis, and get_attribution_evidence for why it is attributed.
| Name | Required | Description | Default |
|---|---|---|---|
| threat_id | Yes | Threat ID (e.g. TL-2026-0042) |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| threat_id | Yes | |
| transcripts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds value beyond annotations by disclosing the semantic nature of the returned data: provenance, not analysis, and stubs rather than prose. This corrects a realistic misreading of the tool name (transcripts as analyst discussion) and tells the agent what not to expect from the output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the key distinction (provenance vs. analysis), then enumerates the useful return components, then gives the caveat and routing guidance. It is slightly dense — the full enumeration of the 7 phases and gate metrics could be trimmed — but every clause earns its place, as it shapes an agent's expectations about content the name misleadingly implies.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return-value mechanics are covered structurally. For a one-parameter read-only tool, the description is complete: what it returns, what it does not contain, how the parts fit together (phases, gates, score, handoff log, correlation highlights), and how to choose among siblings. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with the single threat_id parameter fully documented (type, description, example 'TL-2026-0042'), so the schema does the heavy lifting. The description does not add parameter-specific semantics beyond the example already in the schema, which is acceptable at full coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States precisely what is returned: the 'PIPELINE PROVENANCE record,' and immediately disambiguates it from analysis with 'how its profile was produced, not analysis of the threat itself.' The description names the resource (pipeline phases, quality gates, handoff log) with enough specificity that an agent can distinguish it from get_threat, get_threat_enrichment, and get_attribution_evidence without opening their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is given: 'Use this to judge how thoroughly a threat was worked and to find its related-threat/IOC leads,' followed by named alternatives with their purposes ('use get_threat or get_threat_enrichment for the analysis, and get_attribution_evidence for why it is attributed'). The description also sets a negative expectation — handoff messages are routing stubs, not analyst prose — preventing a likely misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tool_intelligenceTool IntelligenceARead-onlyIdempotent
Pivot on an offensive tool / utility / RMM / LOLBin by name (e.g. "Cobalt Strike", "Mimikatz", "AnyDesk", "PsExec"). Returns the canonical tool + class, prevalence, the threats and actors using it, and its most-common ATT&CK techniques. prevalence.actor_count is the TRUE distinct-actor total; the actors[] array is clipped to the top 20 (see prevalence.actors_returned) — do not read its length as the population.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Tool name (e.g. "Cobalt Strike", "Mimikatz") |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | No | |
| actors | No | |
| matched | Yes | |
| threats | No | |
| canonical | No | |
| membership | No | |
| prevalence | No | |
| entity_type | No | |
| top_techniques | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description surfaces a critical behavioral nuance: prevalence.actor_count is the true distinct-actor total, while the actors[] array is clipped to the top 20 and must not be mistaken for the full population. This is genuinely useful behavioral guidance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: an actionable purpose sentence, an output summary sentence, and a focused data-read confusion caveat. Every sentence earns its place and no structured schema details are merely repeated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter lookup with a full input schema and an output schema present, the description provides all needed context: what kinds of names are valid, what is returned, and how to interpret prevalence counts. No critical clarity gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already defines the single 'name' parameter, and the description expands it by narrowing the valid domain to offensive tools/utilities/RMMs/LOLBins and providing concrete examples. This adds value beyond the schema's generic 'Tool name' description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific, actionable operation: pivot by tool name and return canonical tool data, class, prevalence, threats, actors, and ATT&CK techniques. It gives examples that distinguish it from sibling intelligence tools like get_malware_intelligence or get_actor_intelligence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly defines when to use this tool: when you need intelligence about an offensive tool, utility, RMM, or LOLBin by name. It does not explicitly contrast with sibling tools, but its domain and input expectations are concrete enough to route an agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
healthHealth CheckARead-onlyIdempotent
Lightweight liveness probe: confirms the API is reachable and your key is valid, and returns platform counts + the latest debrief date.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | 'ok' | 'degraded' |
| tool_count | No | Tools the LIVE server exposes. If your client listed fewer, its catalog is stale. |
| catalog_hint | No | |
| prompt_count | No | |
| wire_version | No | Negotiated MCP protocol version. |
| api_reachable | No | |
| catalog_source | No | Always 'live' here — this response came from the server, not a cached catalog. |
| platform_stats | No | |
| server_version | No | |
| latest_debrief_date | No | |
| min_recommended_client | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that the tool is read-only, idempotent, and non-destructive. The description adds useful behavioral context by noting that key validity is checked and that platform counts plus the latest debrief date are returned. There is no contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-front-loaded sentence that conveys the tool's purpose, scope, and outputs without filler. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters, rich annotations, and an output schema, the description is complete for a health-check tool. It tells the agent what the call verifies and what data comes back, and nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there are no parameter semantics for the description to clarify. The schema is already fully straightforward, giving a baseline of 4; the description does not need to compensate for any missing parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific purpose: it is a lightweight liveness probe that confirms API reachability and key validity, and it names what it returns (platform counts and latest debrief date). This clearly distinguishes it from the many data-retrieval sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage as a lightweight connectivity and credential check, but it does not explicitly say when to prefer this over siblings like get_platform_stats or get_latest_debrief, nor does it state when not to use it. The guidance is inferred rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
huntHunt (TLQL)ARead-onlyIdempotent
Run a deterministic SIEM-style query over the pre-joined observation index (~106k rows across tool, malware, ioc, mitre, cve, attribution, dns and infra observations). Use this INSTEAD of chaining many search_threats calls when the question is an aggregate ("how many X grouped by Y") or crosses observation types ("threats using tool A that also have IOC type B"). Append "| stats count by " to aggregate; without it you get matching rows. A threat contributes one row per observation, so for "how many THREATS" use "| stats count_distinct(threat) by " — plain count double-counts. Operators are = != > < >= <= LIKE CONTAINS IN "NOT IN"; quote any value with a hyphen (cve = "CVE-2024-3400"). Call hunt_schema first if you do not know the field names.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Row cap for non-stats queries (default 50, max 100). In stats mode it caps the number of GROUPS returned. Check `has_more` in the response. | |
| query | Yes | TLQL, e.g. `tool = "cobalt strike" AND sector = "healthcare" | stats count by nation` |
Output Schema
| Name | Required | Description |
|---|---|---|
| by | No | |
| func | No | |
| mode | Yes | 'stats' when the query has a | stats pipe, otherwise rows. |
| rows | No | |
| count | No | Rows RETURNED, not rows matched. |
| limit | No | |
| query | Yes | |
| groups | No | |
| columns | No | |
| has_more | No | True when rows (or, in stats mode, groups) were cut at the limit. |
| tier_gated_included | No | True when the caller's tier allows the c2_beacon/dns/infra observation types. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint, openWorldHint, and destructiveHint, but the description adds substantial behavioral context: deterministic semantics, row-per-observation behavior, stats vs non-stats output, count_distinct to avoid double-counting, operator list, and hyphen-quoting rule. These details are not visible in annotations or schema alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although dense, every sentence adds distinct operational guidance: when to use, how to aggregate, how to avoid double counting, supported operators, and required validation. There is no wasteful filler, and the most important usage signal is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers the full calling context: when to use, what the query does, how aggregation works, edge cases like hyphenated values, and the need to consult hunt_schema. The output is covered by the output schema and has_more reference, so the agent has everything needed to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes the parameters, but the description adds practical semantics for the query parameter: example TLQL, supported operators, quoting rules, stats syntax, and the count_distinct caveat. The limit parameter is also explained in the schema, while the description deepens the understanding of query behavior beyond the schema examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Run a deterministic SIEM-style query') and a specific resource ('pre-joined observation index'), and clarifies the kind of questions it answers: aggregates or queries crossing observation types. It explicitly contrasts with search_threats, making sibling differentiation clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this tool INSTEAD of chaining many search_threats calls for aggregate questions or cross-observation-type questions. It also instructs calling hunt_schema first when fields are unknown, going beyond a simple 'when to use' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hunt_schemaHunt SchemaARead-onlyIdempotent
The hunt query grammar: every filterable field and alias, which fields are scoped observables vs denormalized, the operators, the stats-pipe form, worked examples, and how fresh the index is. Call once before writing a hunt query.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| grammar | Yes | |
| row_count | No | |
| rebuilt_at | No | |
| duration_ms | No | |
| by_type_json | No | JSON string of per-observation-type row counts. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds substantive context: index freshness, coverage of the grammar, and a stable 'call once' nature. No contradiction exists between the description and annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences contain no filler. The content inventory is front-loaded and the usage instruction is direct.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool returns, when to call it, and how often. Combined with strong annotations and an output schema, an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and schema coverage is complete, so the description does not need to explain parameters. The content description is relevant and sufficient for a no-argument schema reference.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as the authoritative source for the hunt query grammar, enumerating exactly what it contains: fields, aliases, operators, stats-pipe form, examples, and index freshness. This distinguishes it from the sibling hunt tool and other data-retrieval tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Call once before writing a hunt query' gives explicit when-to-use guidance and implies the result can be cached. It does not name alternatives or exclusions, but the tool is a targeted reference with no obvious alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_campaignsList Named CampaignsARead-onlyIdempotent
Roster of NAMED campaigns/operations referenced by the corpus, with the actors, nation-states, date range and member threats behind each. Answers the campaign-lineage question the other tools cannot: get_campaign_intelligence needs you to already know a name, and get_graph_campaigns only reports the engine's own similarity clusters. Filter with min_actors to find campaigns carrying two or more distinct actors. Each member carries text_supported — whether the campaign name literally occurs in that threat's own record — because the underlying table has no provenance column and at least one row attaches a threat to a campaign with no textual basis, manufacturing a cross-nation link. Check unsupported and cross_nation before treating campaign co-membership as correlation evidence.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 50, max 200. | |
| min_actors | No | Only campaigns with at least this many DISTINCT actor labels (e.g. 2 for multi-actor campaigns). |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| total | No | |
| caveat | Yes | Explains text_supported and its false negatives. Do not drop it when summarising. |
| coverage | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and idempotentHint=true, and the description does not contradict them. It adds substantial behavioral detail beyond those annotations, including that each member carries `text_supported`, that the underlying table lacks a provenance column, and that some rows attach threats to campaigns without textual evidence — warning against treating co-membership as correlation evidence.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the first gives purpose and scope, the second distinguishes it from alternatives, the third gives a filtering example, and the last discloses important data-quality caveats. There is no filler or repetition, and the key scoping information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read-only list tool, this description is complete. It explains what the returned members contain, flags data-quality risks, gives a filtering example, and places the tool among it will provide a missing capability that its siblings don't. The annotations and output schema cover the remaining expectations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters. The description adds extra meaning for min_actors by giving a concrete use case (finding campaigns with two or more distinct actors) and reinforces the significance of fields like `unsupported` and `cross_nation`. It does not add anything about limit, but the schema covers that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: a roster of NAMED campaigns/operations referenced by the corpus, including their actors, nations, date range, and member threats. It also differentiates the tool from get_campaign_intelligence and get_graph_campaigns, making the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains when this tool is the right choice: it answers the campaign-lineage question that get_campaign_intelligence cannot answer because that tool requires a known name, and get_graph_campaigns cannot because it only returns engine similarity clusters. It also gives a concrete filter example with min_actors, which further clarifies intended usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_debriefsList DebriefsARead-onlyIdempotent
List recent daily intelligence debriefs (newest first) with their per-day rollups: new/updated threats, the day's theme, top categories and actors, severity counts, mitre_technique_count (+ mitre_techniques_sample, the first 10 of an alphabetically-sorted ID list — NOT a top-10), and ioc_breakdown by type with ioc_total. Enough to pick the day worth drilling into without fetching each one; use get_debrief for a date's full detail (all techniques, per-threat lists, highlights). Pass limit (default 30, max 100); the result includes has_more (true when the page is full, so older debriefs may exist). NOTE: the debriefs endpoint does not yet honor offset — it serves the most recent window.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max debriefs to return (default 30, max 100) |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| total | No | Total matching rows, when the handler reports one. |
| has_more | No | True when another page may exist. |
| next_cursor | No | Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already state readOnlyHint, idempotentHint, and destructiveHint. The description adds important nuance: 'newest first', the presence of has_more when the page is full, that offset is not honored, and that mitre_techniques_sample is a 'NOT AMAN' first-10 alphabetical list rather than a top-10. This goes well beyond the annotations and prevents an agent from making incorrect assumptions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is packed with useful behavioral context, but it also enumerful detail of the output fields (new/updated threats, theme, categories, actors, severity counts, and more) even though an output schema exists. Those are not strictly needed and make the description longer to parse, though it remains well-structured and legible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even with an output schema and simple parameter, the description supplies all key contextual steps: the listing purpose, the sibling routing, the has_more pagination flag, the offset limitation, and the ordering. An agent can confidently decide to call the tool and interpret its lack without extra refinement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter limit is already documented with its default and max in the parameter description. The tool description merely repeats that ('Pass limit (default 30, max 100)') without adding any new meaning. Baseline for full schema coverage applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'List' with a clear resource ('recent daily intelligence debriefs') and states that results are 'newest first'. It also explicitly contrasts itself with get_debrief, distinguishing the tool from its closest sibling and making the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool ('Enough to pick the day worth drilling into') and when to use the alternative ('use get_debrief for a date's full details'), and describes the limitation that offset is not honored. The instruction is clear and directly names the alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_simulationsList SimulationsARead-onlyIdempotent
DEPRECATED (generation stopped 2026-08-03; archived rows only). List adversary-emulation simulation scenarios across the platform (atomic test commands grouped by threat). total / total_simulations are CORPUS-wide; the page you got is returned / page_simulations, and has_more + next_offset walk the rest. The correlation block (shared_techniques, attack_chain_similarities, platform/tactic coverage) is computed over the RETURNED PAGE only — it carries scope:"page" and changes with limit. Pass limit (default 50, max 200) and offset. include_facets=true adds the corpus filter vocabulary (~20 KB of actor/nation/category strings) — off by default. Prefer get_flow_coverage and get_attack_flow — ATT&CK Flows replaced simulations.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max threats in this page (default 50, max 200) | |
| offset | No | Row offset for paging (default 0). Use next_offset from the previous response. | |
| include_facets | No | Include the corpus filter vocabulary (filter_meta). Default false — it is ~20 KB and does not shrink with limit. |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | No | Corpus-wide threats that have simulations. |
| threats | No | |
| has_more | No | |
| returned | No | Threats in THIS page. |
| deprecated | No | |
| correlation | No | |
| filter_meta | No | |
| next_offset | No | |
| page_simulations | No | Simulation rows across the returned page only. |
| total_simulations | No | Corpus-wide simulation rows. |
| generation_stopped | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, but the description adds rich behavioral context beyond these: deprecation and data availability, corpus-wide vs page-scoped counts, correlation block scope, the default-off facet payload, and pagination using has_more/next_offset. This far exceeds what the annotations alone provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured, front-loading the critical DEPRECATED warning and then layering pagination, correlation, and replacement guidance. It is longer than average, but the length is justified by important behavioral caveats; mild redundancy appears around the max 200 stating that limit, but not enough to obscure the value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool of this complexity, the description covers all needed invocation context: deprecation status, what the columns mean, pagination mechanics, scope-scaling behavior, optional payload size, and the preferred replacement tools. With an output schema also present, the agent has everything needed to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% description coverage for limit, offset, and include_facets, and the description largely repeats those details, such as default 50 and max 200. It does add minor new meaning about facets containing 'actor/nation/category strings', but overall it does not significantly enhance parameter understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List adversary-emulation simulation scenarios across the platform (atomic test commands grouped by threat)'. It also clearly distinguishes this tool from related siblings by explicitly naming get_flow_coverage and get_attack_flow, and marking the tool as DEPRECATED, so an agent can tell exactly what this tool does and why it differs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-not-to-use guidance by declaring the tool deprecated and stating that 'Prefer get_flow_coverage and get_attack_flow — ATT&CK Flows replaced simulations'. It also explains the archived-rows-only nature, making the alternative recommendation clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_threat_categoriesList Threat CategoriesARead-onlyIdempotent
List every threat category with its threat count across the whole corpus. Use to discover valid category filters for search_threats.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| total_categories | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well established. The description adds value by confirming the operation is comprehensive ('every threat category') and returning 'threat count' per category. No contradictions with annotations. Lacks detail on pagination or output size, but for a zero-parameter list tool this is arguably unnecessary.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste. The first sentence states the action and output; the second gives the practical use case. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters, an output schema exists, and rich annotations cover safety/idempotency, the description is complete. It explains what is returned (categories + counts), scope (whole corpus), and the primary use case. No further detail is needed for this simple listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are 0 parameters and schema coverage is 100% (empty properties object fully documented). The description adds no parameter info, which is appropriate since there are none to document. Baseline 4 for a tool with no parameters is justified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource ('list threat categories'), clear scope ('across the whole corpus'), and states what data is returned (threat count per category). Distinct from siblings like search_threats and get_threat, which operate on individual threats/categories. No ambiguity in purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the use case: 'Use to discover valid category filters for search_threats.' This gives the agent clear guidance on when to invoke this tool and how the output feeds into downstream workflow. While it doesn't explicitly enumerate exclusions, the stated purpose effectively differentiates it from the many search/intelligence siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
predict_mitre_transitionsPredict MITRE TransitionsARead-onlyIdempotent
Predict the MITRE ATT&CK techniques most likely to follow (or precede) a given technique, with probabilities and example threats. Each row carries order_basis: 'attack_flow' rows come from analyst-authored ATT&CK Flow DAGs (real asserted causality), 'mitre_canonical' rows are inferred by sorting a threat's flat technique set by canonical tactic rank, and 'blended' rows have both. Prefer attack_flow evidence: ~24% of real transitions run against canonical tactic order and are inexpressible by the canonical basis. Use forward to anticipate the next step; reverse to infer what came before.
| Name | Required | Description | Default |
|---|---|---|---|
| basis | No | Filter by evidence basis. Default 'any' (unfiltered, byte-identical to previous behaviour). Use 'attack_flow' for authored-causality rows only. | |
| top_n | No | Max transitions to return (default 5, max 20) | |
| direction | No | 'forward' = techniques that typically follow (default); 'reverse' = techniques that typically precede | |
| technique_id | No | Source technique ID (e.g. T1059 or T1059.001) |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | |
| total | No | |
| direction | No | |
| transitions | No | |
| technique_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only/idempotent annotations, the description explains how each row is generated: attack_flow rows come from analyst-authored DAGs, mitre_canonical is inferred from tactic rank, and blended has both. It also discloses the limitation that ~24% of real transitions are inexpressible by the canonical basis, which is valuable behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence adds distinct information: purpose, evidence-basis semantics, preference recommendation, and direction intent. The structure is front-loaded with the core prediction behavior followed by necessary nuance, with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich parameter schema, enums, output schema, and annotations, the description is sufficiently complete. It covers what the tool returns, how the data is derived, how to pick basis and direction, and a key limitation. Nothing necessary for successful invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all four parameters, so the baseline is 3. The description adds operational meaning for basis (attack_flow vs mitre_canonical vs blended) and direction (forward vs reverse) beyond the schema descriptions. It does not add much for top_n or technique_id, but the schema covers those sufficiently.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names the specific action (predict), resource (MITRE ATT&CK techniques), and conditionality (follow/precede a given technique) with probabilities and examples. This clearly distinguishes the tool from sibling functions focused on coverage, technique details, or raw attack flows.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage direction: prefer attack_flow evidence, use forward to anticipate the next step, and reverse to infer what came before. It also explains which basis to prefer and why, giving an agent actionable selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_entityResolve Canonical NameARead-onlyIdempotent
Normalize an actor / malware / tool / sector / region / technique name or alias to its canonical reference form + stable UUID (e.g. "fancy bear" → "APT28"). Call this BEFORE pivoting (get_actor / get_malware_intelligence / get_tool_intelligence / search_threats) when unsure of the canonical name. Optional type narrows the lookup.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name or alias to resolve | |
| type | No | Optional: actor|malware|tool|sector|region|technique|campaign |
Output Schema
| Name | Required | Description |
|---|---|---|
| uuid | No | |
| query | Yes | |
| matched | Yes | |
| canonical | No | Canonical name — feed to get_actor / get_malware_intelligence / get_tool_intelligence. |
| entity_type | No | |
| matched_via | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the return contract (canonical reference form + stable UUID) and the type-narrowing behavior. It doesn't describe edge cases like unmatched names, but with strong annotations plus stated return contract, a 4 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with zero waste. Every clause earns its place: the normalization behavior, the example, the explicit call sequencing, and the type note. Ideally front-loaded and highly scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (2 params, 1 required), has an output schema (so return format is documented elsewhere), has high schema coverage, and strong annotations. The description covers purpose, usage context, return type, and specific integration points. There is genuinely nothing missing for an agent to correctly invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% — both parameters (name, type) are described in the schema. The description adds the type enum semantics ('Optional type narrows the lookup') which supplements the schema's type list. Parameter info added beyond schema is present but minimal, so baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Normalize') with a clear resource (entity names/aliases to canonical form + UUID), provides a concrete example ('fancy bear' → 'APT28'), and explicitly differentiates it from get/search tools. Purpose is unambiguous and distinct from all siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to call this tool ('BEFORE pivoting to get_actor / get_malware_intelligence / get_tool_intelligence / search_threats when unsure of the canonical name'). This gives crystal-clear sequencing guidance and names the exact alternative tools it pairs with, exceeding a simple when-to-use statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_actorsList ActorsARead-onlyIdempotent
List attributed threat actors with aggregate stats (threat_count, severity levels, categories, nation_state). Returns the full roster in one call, or narrow it with the optional tool / malware / sector filters (e.g. tool="Cobalt Strike" → only actors that used it). Use get_actor for a single actor's full profile. Not paginated; the response carries a total count. Names are REPAIRED before they are returned: the corpus stores threat_actor as free text and comma-split it, so prose fragments and truncated parentheticals used to appear as adversaries — label_hygiene reports what was dropped and repaired. Two per-row flags matter: role: "co-mention" means the corpus never files a threat under that name as its primary attribution, and also_grounded_as means the corpus also records the name as a malware family or tool (e.g. SNOWLIGHT). Check both before reporting a row as an operator.
| Name | Required | Description | Default |
|---|---|---|---|
| tool | No | Only actors with a threat using this tool (e.g. "Cobalt Strike") | |
| sector | No | Only actors with a threat targeting this sector (e.g. "Healthcare") | |
| malware | No | Only actors with a threat deploying this malware family (e.g. "LockBit") |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | No | Total matching rows, when the handler reports one. |
| actors | No | |
| has_more | No | True when another page may exist. |
| next_cursor | No | Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset. |
| label_hygiene | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses data-repair behavior, label_hygiene reporting, the meaning of role: co-mention and also_grounded_as, and non-pagination with a total count. This meaningfully helps an agent interpret returned rows correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is more verbose than average, but every sentence earns its place: purpose, filtering, sibling routing, pagination, and two critical data-quality warnings. It is front-loaded with the main verb and resource.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a listing tool, it covers the full behavioral envelope: default and filtered behavior, single-actor alternative, output size expectations, and interpretation of per-row flags. The existing output schema carries the mechanical return shape, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter has a one-line description, so the baseline is 3. The description adds semantic clarity by showing that filters narrow the full roster and provides a concrete example of how filtering behaves.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List attributed threat actors with aggregate stats,' and explicitly contrasts itself with get_actor for single-actor profiles. It immediately distinguishes itself from sibling actor tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly explains both modes: full roster in one call versus narrowing via optional filters, provides a concrete example with tool='Cobalt Strike', and directs users to get_actor for single-actor detail. It also states the pagination behavior, leaving no guesswork.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_corpus_semanticSemantic Corpus SearchARead-onlyIdempotent
Vector + rerank retrieval over the whole corpus, returning ranked source cards. Use when keyword search fails — conceptual or paraphrased questions where the exact terms do not appear in the text. Complements search_threats, which is boolean/exact over structured filters. Depends on the AI Search binding and is rate-limited; a 503 means the index is unavailable, not that nothing matched.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | A natural-language question or concept. |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | No | |
| chunks | No | |
| results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered by structured data. The description adds genuine value beyond annotations: it discloses the AI Search binding dependency, rate-limiting behavior, and crucially that a 503 means index unavailability rather than no match — an important interpretive insight for agents handling errors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, zero filler. The opening sentence states purpose and output, the second provides usage guidance, and the third covers dependencies and error interpretation. Every sentence earns its place with no redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite being a single-param tool, it's sufficiently complex (retrieval strategy, ranking, dependencies, rate limits, error semantics) and the description covers all of these dimensions. With an output schema present, return-value explanation is unnecessary. The description is complete for an agent to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% — the single query parameter is documented in the schema as 'A natural-language question or concept.' The description reinforces this with 'Vector + rerank' language and returning 'ranked source cards,' but doesn't add significant format or syntax semantics beyond what the schema already provides. Baseline 3 is appropriate given full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource+mechanism ('Vector + rerank retrieval over the whole corpus, returning ranked source cards'). It clearly distinguishes itself from sibling search_threats, which is described as 'boolean/exact over structured filters,' providing a strong sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('conceptual or paraphrased questions where the exact terms do not appear in the text'), when not to use ('when keyword search fails' implies use alternative first), and names the exact alternative (search_threats). This is textbook explicit when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_detectionsSearch DetectionsARead-onlyIdempotent
Keyword search across detection logic (SPL/KQL/Sigma) by rule text, technique, or threat. Optionally filter by type (spl|kql|sigma) or severity. Paginated via limit (default 25, max 200) + offset.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Detection type: spl, kql, or sigma | |
| limit | No | Max results (default 25, max 200) | |
| query | Yes | Search term (rule text, CVE, technique, etc.) | |
| offset | No | Row offset for pagination (default 0) | |
| severity | No | Filter by severity: critical, high, medium, low |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is already covered. The description adds value beyond annotations: it discloses pagination behavior (limit default 25/max 200 via offset) and the filter semantics. It doesn't describe the return format, but an output schema exists which covers that. Reasonable balance given the strong annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose, and packs significant information: search domain (SPL/KQL/Sigma), search dimensions (rule text/technique/threat), filters (type/severity), and pagination (limit default/cap, offset). Zero filler or redundant restating of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with an output schema, 100% parameter schema coverage, and strong annotations (readOnly, idempotent), the description is complete. It specifies search domains, filters, pagination defaults/caps, and scope. The output schema handles return-value documentation. Nothing meaningful is left unspecified for an agent to execute a correct search.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 5 parameters. The description adds value by enumerating the filter dimensions (type, severity, pagination with defaults) and search scope (rule text, technique, threat), providing semantic context like 'keyword search' that ties the parameters together coherently. It slightly exceeds the baseline 3 by framing how type/severity combine with the query.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource: 'Keyword search across detection logic (SPL/KQL/Sigma) by rule text, technique, or threat.' It clearly distinguishes from siblings like search_vulnerabilities, search_threats, search_iocs, and get_detections (which likely returns all detections without search). The scope (rule text/technique/threat) and optional filters (type, severity) are explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context: search across detection logic by rule text/technique/threat. It doesn't explicitly name sibling alternatives to contrast against, but the type filter (spl|kql|sigma) and severity option provide clear when-to-use context. It doesn't explicitly state when NOT to use it (e.g., use get_detections for unfiltered listing), but siblings with distinct names make this largely inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_iocsSearch IOCsARead-onlyIdempotent
Search indicators of compromise (IPs, domains, hashes, URLs). Filter by value substring and/or category. Pass limit (default 25, max 100); the result includes has_more (true when the page is full, so more may exist). NOTE: the indicator endpoint does not yet honor offset — narrow with a more specific value/type substring rather than paging.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | IOC category (e.g. network, file, behavioral) | |
| limit | No | Max results (default 25, max 100) | |
| value | No | Substring to match against IOC values |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| total | No | Total matching rows, when the handler reports one. |
| has_more | No | True when another page may exist. |
| next_cursor | No | Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true and destructiveHint=false annotations already establishing safety, the description adds valuable behavioral context: the has_more semantics, the limit cap, and the critical note that offset isn't honored (so paging won't work). This functional caveat is genuinely useful behavioral disclosure beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Compact two-sentence description, front-loaded with purpose. The parenthetical about the offset limitation is efficiently integrated rather than a separate paragraph. Slightly dense but every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema is present and a 3-param tool with 100% schema coverage, the description covers purpose, filtering modes, limit behavior, and the unusual offset caveat. The sibling landscape has many IOC-adjacent tools, so explicit guidance on when to use this vs search_xscan_indicators would push it to 5, but for its complexity level the completion is strong.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds the note on narrowing with more specific substrings instead of paging, which adds a bit of guidance, but the description largely restates what schema already documents (type/value/limit defaults). No new semantic detail beyond defaults and pagination caveat.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb+resource: 'Search indicators of compromise' with specific types listed (IPs, domains, hashes, URLs). Distinguishes from siblings like search_vulnerabilities and search_threats by naming the IOC domain, though it doesn't explicitly name sibling alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States filtering modes (value substring and/or category) and the limit behavior with the has_more flag. However, it doesn't explicitly say when to choose this over search_xscan_indicators or get_ioc_intelligence, which are nearby siblings operating on IOCs. The note about offset not being honored provides usage constraint context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_threatsSearch ThreatsARead-onlyIdempotent
The deterministic threat-catalog query tool. Returns LEAN summary rows {id, title, severity, category, status, threat_actor, nation_state, affected_products, cves, cvss_score, summary, created} — call get_threat for full detail on a specific id. Combine a free-text query with any structured filters; ALL filters AND-combine and apply together (e.g. query="supply chain" + threat_actor="TeamPCP" + category="SUPPLY_CHAIN" returns only matching rows, with affected_products inline). Paginated: limit (default 20, max 100) + offset/cursor; result carries total, has_more, and next_cursor.
| Name | Required | Description | Default |
|---|---|---|---|
| os | No | Filter to threats affecting an operating system (e.g. "Windows", "Linux", "VMware ESXi") | |
| cve | No | Filter by CVE id (e.g. CVE-2026-45321) | |
| tag | No | Filter by exact tag (e.g. "supply-chain-compromise") | |
| tool | No | Filter to threats using a tool (e.g. "Cobalt Strike", "Mimikatz") | |
| limit | No | Max results (default 20, max 100) | |
| query | No | Free-text term across title/summary/description/CVE/actor (optional; AND-combined with filters) | |
| cursor | No | Opaque pagination cursor (next_cursor from a prior result); ignored when offset is given. | |
| offset | No | Row offset for pagination (default 0). | |
| sector | No | Filter by grounded industry sector (e.g. "Healthcare", "Government") | |
| status | No | Threat status filter (e.g. active) | |
| malware | No | Filter to threats deploying a malware family (e.g. "LockBit", "Vidar") | |
| campaign | No | Filter to threats in a named campaign/operation (e.g. "Snowflake campaign") | |
| category | No | e.g. SUPPLY_CHAIN, MALWARE, RANSOMWARE, VULNERABILITY, APT, PHISHING, ZERO_DAY (call list_threat_categories for the full vocabulary) | |
| severity | No | critical | high | medium | low | |
| motivation | No | Filter by motivation (e.g. financial, espionage) | |
| nation_state | No | Filter by nation-state (e.g. Russia, China, Iran) | |
| threat_actor | No | Filter by attributed actor name/alias (e.g. "TeamPCP", "APT29") | |
| created_after | No | ISO date — only threats created on/after (e.g. 2026-05-01) | |
| target_region | No | Filter by targeted region (e.g. APAC, Europe) | |
| target_sector | No | Filter by targeted sector (e.g. Healthcare, Finance) | |
| created_before | No | ISO date — only threats created on/before | |
| mitre_technique | No | Filter by MITRE technique id (e.g. T1059) | |
| affected_product | No | Filter by affected product/vendor (e.g. "npm", "Microsoft", "VS Code") |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| total | No | Total matching rows, when the handler reports one. |
| has_more | No | True when another page may exist. |
| next_cursor | No | Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is covered. The description adds valuable behavioral context beyond annotations: the tool is deterministic, returns LEAN summary rows (not full records), and discloses pagination mechanics (total, has_more, next_cursor, cursor vs offset precedence). This is genuinely useful behavioral disclosure over and above what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences that each earn their place: the first defines output fields and full-detail redirect, the second explains filter combination semantics with a concrete example, the third covers pagination. No filler, no repetition of schema content, and result fields are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, an output-bearing description is not strictly required, yet it still names the exact fields. The description covers output shape, filter semantics, pagination, deterministic behavior, and the full-detail alternative. For a 23-parameter filtered-list tool with rich annotations and output schema, nothing material is left unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all 23 parameters are documented in the input schema, making the baseline 3. The description adds meaning around combine semantics (AND-combining of all filters) and cross-references the category parameter to list_threat_categories, which goes slightly beyond the schema. However, most parameter behavior is already well-covered by the schema, so the description doesn't need to compensate much.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool is a deterministic threat-catalog query tool that returns LEAN summary rows, explicitly listing the exact fields returned. It distinguishes from siblings by noting 'call get_threat for full detail on a specific id' and contrasts with search_vulnerabilities (different resource). The specific verb 'search/query' plus the deterministic qualifier and resource (threat-catalog) make the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains how filters AND-combine with a free-text query, provides a concrete multi-filter example ('query="supply chain" + threat_actor="TeamPCP" + category="SUPPLY_CHAIN"'), and directs the agent to call get_threat for full detail — clear when-to-use and when-not-to-use guidance versus its sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_vulnerabilitiesSearch VulnerabilitiesARead-onlyIdempotent
Query the real-time CVE feed — validated against CVE.org and enriched from open sources (CVSS, EPSS exploitation probability, CISA KEV, public PoCs/exploits, nuclei detection templates, affected products/packages, plus platform-native trending/priority). Sort by trending|latest|priority|cvss|epss; filter by severity, kev (KEV-only), has_poc, nuclei, epss_min, window (days), vendor, cwe, or free-text query. Returns COMPACT cards {cve_id, severity, cvss, epss_percentile, is_kev, has_poc/exploit/nuclei, priority, trending, vendors, age} — call get_cve(id) for full detail.
| Name | Required | Description | Default |
|---|---|---|---|
| cwe | No | Weakness id, e.g. CWE-79 | |
| kev | No | Only CISA KEV (known-exploited) CVEs | |
| sort | No | trending (default) | latest | priority | cvss | epss | |
| limit | No | default 30, max 100 | |
| query | No | Free-text: a CVE id or keyword (matches id + description) | |
| nuclei | No | Only CVEs with a nuclei detection template | |
| vendor | No | Affected vendor/product substring | |
| window | No | Only CVEs published within the last N days | |
| has_poc | No | Only CVEs with a public proof-of-concept | |
| epss_min | No | Minimum EPSS exploitation probability, 0-1 | |
| severity | No | CRITICAL | HIGH | MEDIUM | LOW |
Output Schema
| Name | Required | Description |
|---|---|---|
| sort | No | |
| total | No | |
| facets | No | |
| pagination | No | |
| vulnerabilities | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds genuine value: states data is 'validated against CVE.org and enriched', reveals the COMPACT card return shape, and notes the default sort='trending'. Slightly less on pagination/rate limits but the compact-return disclosure is a strong contribution beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly-packed sentences with zero filler. All heavy detail is front-loaded in the first sentence. Slightly dense—the second sentence lists many filter options that partially duplicate the schema—but no wasted words. The return-format disclosure in the description is genuinely additional value, not repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only search tool with 100% schema coverage, an output schema, and full annotation coverage, this is complete. The description explains data provenance, enrichment sources, all filter dimensions, sort modes, defaults, and the compact return shape—plus points the agent to get_cve for more detail. Nothing material is left undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of parameters, so baseline is 3. The description adds meaning beyond the schema: explains the card fields (cve_id, severity, cvss, epss_percentile, is_kev, etc.), reveals the default sort behavior, and explains that free-text query 'matches id + description'. This value-add justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb+resource: 'Query the real-time CVE feed' with explicit sourcing (CVE.org, CVSS, EPSS, CISA KEV, PoCs, nuclei). Distinguishes from siblings: notably get_cve is referenced as the companion for full detail, and search_threats/search_iocs are different resource types.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Extremely explicit: names all sort modes, filter dimensions, and return format. Explicitly says 'call get_cve(id) for full detail', providing a clear when-to-use-alternative instruction. Enumerates every available filter so the agent knows exactly what this tool supports.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_xscan_indicatorsSearch Community IndicatorsARead-onlyIdempotent
Search the canonical community-indicator set (TL_OSINT_Scan / tweetfeed.live, CC0) — indicators the community reported that were also matched against our corpus. Filter by tag, type, ASN, country, minimum linked-threat count, or a value substring. There is deliberately NO family filter: the upstream AI family field is populated on under 1% of rows, so a family argument would return nothing. Use tag instead (community tags carry the family signal). Community-sourced and heavily concentrated (~73% of recent submissions come from a single reporter) — corroborating, not authoritative.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Substring match on the indicator value | |
| asn | No | Autonomous system, e.g. AS14061 | |
| tag | No | Community tag substring, case-insensitive and normalized (e.g. phishing, asyncrat, c2) | |
| type | No | Indicator type | |
| limit | No | Max rows (default 25, max 100) | |
| offset | No | Row offset for paging | |
| country | No | Two-letter country code, e.g. RU | |
| min_threats | No | Only indicators linked to at least this many of our threats |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | |
| total | No | Total matching rows, when the handler reports one. |
| has_more | No | True when another page may exist. |
| next_cursor | No | Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, and the description is consistent. Beyond annotations it adds valuable context: the deliberate absence of a family filter (a non-obvious behavioral trait), the dataset provenance/license (CC0), the 'matched against our corpus' constraint, and the concentration statistic (~73% from a single reporter) that warns the agent not to treat results as authoritative. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each carrying weight: scope+provenance, filter capability, no-family-filter explanation + sourcing caveat. The prose is efficient, but it's dense and could arguably be split into a cleaner scannable form. Still, no filler and front-loaded with the most important information (what the data is and its limitations).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-param search tool with a 100%-described schema, an output schema, and readSafe/idempotent annotations, the description is remarkably complete. It covers data provenance, source quirk (sparse family field), the correct filter strategy (tag vs family), and data-quality caveats (single-reporter concentration, corroborating-not-authoritative). Nothing critical is left unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with all 8 parameters described. The description adds value via examples for the less obvious ones: 'tag' gets 'phishing, asyncrat, c2' examples plus case-insensitive/normalized behavior, 'asn' gets 'AS14061,' and 'country' gets 'RU.' The default-25/max-100 for limit also appears in the description. Minor gap: the 'q' substring and 'min_threats' semantics are adequately covered by schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb+resource+scope: 'Search the canonical community-indicator set (TL_OSINT_Scan / tweetfeed.live, CC0)' with a specific qualification that results were 'matched against our corpus.' This distinguishes from siblings like search_iocs (presumably the authoritative/threat-linked set) by emphasizing community-sourced + corpus-matched nature.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit and rich: explains there is deliberately NO family filter and why (upstream family field populated on <1% of rows), directing the agent to 'Use tag instead (community tags carry the family signal).' Also gives caveat that data is corroborating, not authoritative, which sets expectations on how to weigh results versus search_iocs or search_threats.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
47 tool updates
v8.2.1- Changed
bulk_get_threats8 fields changed- added
Input schema / properties / detailAdded value: +{ + "description": "\"summary\" (default, all 20 fit) | \"full\" (whole dossiers, max 3 ids per call)", + "type": "string" +} - added
Output schema / properties / count / descriptionAdded value: +"Rows actually present in threats[] — safe to iterate on." - added
Output schema / properties / deferred_idsAdded value: +{ + "items": { + "description": "Ids NOT fetched because detail=\"full\" is batch-capped. Call again with these.", + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / deferred_reasonAdded value: +{ + "type": "string" +} - added
Output schema / properties / detailAdded value: +{ + "description": "\"summary\" | \"full\" — which row shape threats[] carries.", + "type": "string" +} - added
Output schema / properties / detail_hintAdded value: +{ + "type": "string" +} - added
Output schema / properties / requestedAdded value: +{ + "description": "How many ids the caller supplied.", + "type": "integer" +} - changed
Output schema / requiredPrevious value: -[ - "threats", - "missing" -]New value: +[ + "threats", + "missing", + "count" +]
- Changed
export_attack_navigator5 fields changed- added
Output schema / properties / descriptionAdded value: +{ + "description": "Includes the scoring unit (\"Score = …\").", + "type": "string" +} - added
Output schema / properties / metadataAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / techniques / items / properties / colorAdded value: +{ + "type": "string" +} - added
Output schema / properties / techniques / items / properties / enabledAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / techniques / items / properties / score / descriptionAdded value: +"Threats using THIS technique (per-technique, not per-tactic). See description/metadata for the unit."
- Changed
get_actor8 fields changed- added
Output schema / properties / actor_relationshipsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "rel_type": { + "type": "string" + }, + "related_name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / actor_relationships_coverageAdded value: +{ + "description": "Present only when actor_relationships is empty: says the baseline has no row, not that the actor is unrelated.", + "type": "string" +} - added
Output schema / properties / mitre / properties / techniques_returnedAdded value: +{ + "type": "integer" +} - added
Output schema / properties / mitre / properties / techniques_totalAdded value: +{ + "description": "Distinct techniques for this actor. technique_ids is capped at 60 — compare the two before reading it as the whole footprint.", + "type": "integer" +} - added
Output schema / properties / mitre / properties / truncation_noteAdded value: +{ + "type": "string" +} - added
Output schema / properties / relationships / properties / shared_infraAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / relationships / properties / shared_techniquesAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / relationships / properties / shared_toolingAdded value: +{ + "items": {}, + "type": "array" +}
- Changed
get_actor_intelligence5 fields changed- added
Output schema / properties / actor_relationshipsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "rel_type": { + "type": "string" + }, + "related_name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / cross_actor_attribution / additionalPropertiesAdded value: +true - removed
Output schema / properties / cross_actor_attribution / descriptionRemoved value: -"Shared entities across actors, or null when the attribution engine has nothing." - added
Output schema / properties / cross_actor_attribution / propertiesAdded value: +{ + "co_actors": { + "items": { + "additionalProperties": true, + "properties": { + "actor": { + "description": "Pass to get_actor / get_actor_intelligence.", + "type": "string" + }, + "by_type": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "max_belief": { + "type": "number" + }, + "shared_entities": { + "type": "integer" + }, + "strongest": { + "additionalProperties": true, + "properties": { + "belief_label": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "entity_value": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + }, + "corpus": { + "additionalProperties": true, + "properties": { + "total_shared": { + "type": "integer" + }, + "unique_actors": { + "type": "integer" + } + }, + "type": "object" + }, + "counts": { + "additionalProperties": true, + "properties": { + "by_belief": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "by_type": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "co_actor_count": { + "description": "Every actor touched by ANY matched row, commodity TTPs included — a breadth number, not an answer.", + "type": "integer" + }, + "co_actors_returned": { + "type": "integer" + }, + "matched": { + "type": "integer" + }, + "returned": { + "type": "integer" + }, + "truncated": { + "type": "boolean" + } + }, + "type": "object" + }, + "scoped_to": { + "description": "The queried actor. Rows below name ONLY this actor or an alias — never the whole corpus.", + "type": "string" + }, + "shared_entities": { + "items": { + "additionalProperties": true, + "properties": { + "actor_count": { + "description": "True co-actor count; actor_list is clipped.", + "type": "integer" + }, + "actor_list": { + "items": { + "type": "string" + }, + "type": "array" + }, + "belief": { + "type": "number" + }, + "belief_label": { + "description": "strong | moderate | weak | commodity — commodity is weak attribution signal.", + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "entity_value": { + "type": "string" + }, + "evidence": { + "items": {}, + "type": "array" + }, + "threat_count": { + "type": "integer" + }, + "threat_ids": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } +} - changed
Output schema / properties / cross_actor_attribution / typePrevious value: -[ - "object", - "null" -]New value: +"object"
- Added
get_actor_relationships - Added
get_atlas_intelligence - Added
get_attack_flow - Changed
get_c22 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max records for paginated views like beacons (default 50, max 100)"New value: +"Max records for the record-bearing views — beacons (default 50), configs (default 25), correlations (default 25). Max 100." - added
Input schema / properties / offsetAdded value: +{ + "description": "Skip this many records — 'correlations' only; the aggregate summary block stays whole across pages.", + "type": "number" +}
- Changed
get_campaign_intelligence5 fields changed- added
Output schema / properties / membershipAdded value: +{ + "additionalProperties": true, + "properties": { + "grounded": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "title_match": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "type": "object" +} - added
Output schema / properties / prevalence / properties / actor_count / descriptionAdded value: +"TRUE distinct-actor prevalence, uncapped. The actors[] array is clipped to 20 — compare with actors_returned." - added
Output schema / properties / prevalence / properties / actors_returnedAdded value: +{ + "type": "integer" +} - added
Output schema / properties / prevalence / properties / threat_count_is_floorAdded value: +{ + "description": "True when the membership fetch saturated, so threat_count under-counts.", + "type": "boolean" +} - added
Output schema / properties / threats / items / properties / matched_viaAdded value: +{ + "description": "campaigns only: grounded | title | grounded+title", + "type": "string" +}
- Changed
get_changelog10 fields changed- added
Output schema / properties / countAdded value: +{ + "type": "integer" +} - added
Output schema / properties / entriesAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "changes": { + "items": {}, + "type": "array" + }, + "date": { + "type": "string" + }, + "id": {}, + "title": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / has_moreAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / latest_entry_dateAdded value: +{ + "description": "Date of the newest entry — the feed cut-off.", + "type": [ + "string", + "null" + ] +} - removed
Output schema / properties / resultRemoved value: -{ - "items": { - "additionalProperties": true, - "properties": { - "changes": { - "items": {}, - "type": "array" - }, - "id": {} - }, - "type": "object" - }, - "type": "array" -} - added
Output schema / properties / staleAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / stale_daysAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / totalAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / warningAdded value: +{ + "description": "Present when the feed is stale; says what it does NOT cover.", + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "result" -]New value: +[ + "entries" +]
- Changed
get_correlation_subgraph12 fields changed- added
Input schema / properties / edge_typeAdded value: +{ + "description": "Keep only edges of this type (also prunes the traversal, so it changes which nodes are reachable). Omit for all types.", + "enum": [ + "actor_technique", + "technique_cooccurrence", + "ioc_threat", + "threat_similarity" + ], + "type": "string" +} - changed
Input schema / properties / min_fidelity / descriptionPrevious value: -"Drop edges below this fidelity (0-1)."New value: +"Drop edges below this fidelity. Scale is 0-100, NOT 0-1 — typical NPMI edges sit between 5 and 30, so 0.5 filters nothing." - added
Output schema / properties / countsAdded value: +{ + "additionalProperties": true, + "properties": { + "edges": { + "type": "integer" + }, + "nodes": { + "type": "integer" + } + }, + "type": "object" +} - added
Output schema / properties / edges / items / properties / co_occurrence_countAdded value: +{ + "type": "integer" +} - removed
Output schema / properties / edges / items / properties / fidelityRemoved value: -{ - "type": "number" -} - added
Output schema / properties / edges / items / properties / fidelity_scoreAdded value: +{ + "description": "Rounded 0-100.", + "type": "number" +} - added
Output schema / properties / edges / items / properties / marginalsAdded value: +{ + "additionalProperties": true, + "properties": { + "N": { + "type": "integer" + }, + "c": { + "type": "integer" + }, + "df_actor": { + "type": "integer" + }, + "df_tech": { + "type": "integer" + } + }, + "type": "object" +} - added
Output schema / properties / edges / items / properties / pmiAdded value: +{ + "description": "NPMI edge types only (actor_technique, technique_cooccurrence).", + "type": "number" +} - added
Output schema / properties / edges / items / properties / weight_normAdded value: +{ + "type": [ + "number", + "null" + ] +} - removed
Output schema / properties / paramsRemoved value: -{ - "additionalProperties": true, - "properties": {}, - "type": "object" -} - added
Output schema / properties / params_echoAdded value: +{ + "additionalProperties": true, + "properties": {}, + "type": "object" +} - added
Output schema / properties / truncatedAdded value: +{ + "type": "boolean" +}
- Changed
get_correlations2 fields changed- added
Input schema / properties / limitAdded value: +{ + "description": "Paged engines only ('mitre-heatmap', 'ioc-consensus', 'detection-debt'): max rows, pre-ordered by score (default 50; max 200 for mitre-heatmap, 500 for the others). The summary block always covers the full set.", + "type": "number" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "Paged engines only: skip this many rows.", + "type": "number" +}
- Changed
get_cve8 fields changed- added
Output schema / properties / affected_products_raw_countAdded value: +{ + "description": "Entries before pre-release CPE collapsing.", + "type": "integer" +} - added
Output schema / properties / enrichment_noteAdded value: +{ + "description": "Present only on 'not_enriched'; names the seeding source.", + "type": "string" +} - added
Output schema / properties / enrichment_statusAdded value: +{ + "description": "'enriched' or 'not_enriched'. On 'not_enriched' a blank CVSS/EPSS/age_days means NOT MEASURED, not measured-empty.", + "type": "string" +} - added
Output schema / properties / threat_countAdded value: +{ + "type": "integer" +} - changed
Output schema / properties / threat_ids / items / descriptionPrevious value: -"Threats exploiting this CVE — pass to get_threat."New value: +"Threats referencing this CVE, from the LIVE threats.cve_list join — pass to get_threat." - added
Output schema / properties / threat_ids_derived_onlyAdded value: +{ + "items": { + "description": "Ids the stale derived index held that the live join does not - unconfirmed historical linkage, deliberately NOT merged into threat_ids.", + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / threat_ids_noteAdded value: +{ + "description": "Present only when the derived cve_details.threat_ids reverse index disagreed with the live join.", + "type": "string" +} - added
Output schema / properties / threat_ids_sourceAdded value: +{ + "description": "Always 'threats.cve_list (authoritative live join)' when the join ran.", + "type": "string" +}
- Changed
get_cve_intelligence10 fields changed- added
Output schema / properties / actorsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "actor": { + "type": "string" + }, + "threat_count": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / cve / properties / threat_idsAdded value: +{ + "items": { + "description": "Reconciled from threats.cve_list — the authoritative join. Pass to get_threat.", + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / cve / properties / threat_ids_noteAdded value: +{ + "description": "Present only when the derived cve_details reverse index disagreed.", + "type": "string" +} - added
Output schema / properties / cve / properties / threat_ids_sourceAdded value: +{ + "type": "string" +} - added
Output schema / properties / mitreAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "tactic": { + "type": "string" + }, + "technique": { + "type": "string" + }, + "technique_id": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / related_cvesAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "cve_id": { + "type": "string" + }, + "is_kev": { + "type": "boolean" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / threatsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "actor": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string" + }, + "severity": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / velocity_data / additionalPropertiesAdded value: +true - added
Output schema / properties / velocity_data / propertiesAdded value: +{ + "cohort_fastest": { + "items": {}, + "type": "array" + }, + "corpus": { + "additionalProperties": true, + "properties": { + "avg_velocity": { + "type": "number" + }, + "total": { + "type": "integer" + } + }, + "type": "object" + }, + "cve": { + "description": "The velocity row for THIS CVE (velocity_days = publication → first tracked threat), or null when it has no tracked linkage.", + "type": [ + "object", + "null" + ] + }, + "note": { + "type": "string" + }, + "rank": { + "description": "{faster_than_pct, position, of} — where this CVE sits in the corpus velocity distribution.", + "type": [ + "object", + "null" + ] + } +} - changed
Output schema / properties / velocity_data / typePrevious value: -[ - "object", - "null" -]New value: +"object"
- Changed
get_cwe10 fields changed- added
Output schema / properties / abstractionAdded value: +{ + "type": "string" +} - added
Output schema / properties / common_consequencesAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / detection_methodsAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / likelihood_of_exploitAdded value: +{ + "description": "MITRE's High/Medium/Low rating. CWE has NO CVSS severity — see severity_note.", + "type": "string" +} - added
Output schema / properties / related_cve_countAdded value: +{ + "description": "True total mapping to this CWE, which can exceed the 20 returned.", + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / related_cvesAdded value: +{ + "description": "Corpus CVEs mapping to this CWE (top 20, KEV then CVSS). NULL means the join could not run — it never means \"none exist\"; [] does.", + "items": { + "additionalProperties": true, + "properties": { + "cve_id": { + "description": "Pass to get_cve.", + "type": "string" + }, + "cvss": { + "type": [ + "number", + "null" + ] + }, + "epss": { + "type": [ + "number", + "null" + ] + }, + "is_kev": { + "type": "boolean" + }, + "is_ransomware": { + "type": "boolean" + }, + "severity": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] +} - added
Output schema / properties / related_cves_noteAdded value: +{ + "type": "string" +} - added
Output schema / properties / related_cwes / items / descriptionAdded value: +"De-duplicated CWE ids — pass to get_cwe." - added
Output schema / properties / related_cwes / items / typeAdded value: +"string" - added
Output schema / properties / severity_noteAdded value: +{ + "type": "string" +}
- Added
get_d3fend_posture - Changed
get_daily_intel_bundle2 fields changed- added
Output schema / properties / detail_hintAdded value: +{ + "type": "string" +} - added
Output schema / properties / top_threats / descriptionAdded value: +"LEAN summary rows (the search_threats shape) — call get_threat(id) for a dossier."
- Changed
get_daily_theme9 fields changed- added
Output schema / properties / tags_noteAdded value: +{ + "type": "string" +} - added
Output schema / properties / themes / items / properties / snapshot_threat_countAdded value: +{ + "description": "How many threats existed when the theme sentence was written.", + "type": "integer" +} - added
Output schema / properties / themes / items / properties / tags / items / additionalPropertiesAdded value: +true - added
Output schema / properties / themes / items / properties / tags / items / propertiesAdded value: +{ + "count": { + "type": "integer" + }, + "tag": { + "type": "string" + } +} - changed
Output schema / properties / themes / items / properties / tags / items / typePrevious value: -"string"New value: +"object" - added
Output schema / properties / themes / items / properties / tags_availableAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / themes / items / properties / tags_sourceAdded value: +{ + "description": "live | snapshot | none.", + "type": "string" +} - added
Output schema / properties / themes / items / properties / theme_noteAdded value: +{ + "description": "Present when the sentence was written from fewer threats than the day ended with.", + "type": "string" +} - added
Output schema / properties / themes / items / properties / threat_count / descriptionAdded value: +"Live count of that date's threats."
- Changed
get_enrichment_overview19 fields changed- added
Output schema / properties / as_ofAdded value: +{ + "description": "Newest row timestamp - this is a nightly snapshot, not a live read.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / noteAdded value: +{ + "description": "States which advertised sources are lanes and which are fields of a lane.", + "type": "string" +} - added
Output schema / properties / sources / items / properties / avg_enrichment_fieldsAdded value: +{ + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / sources / items / properties / coverage_basisAdded value: +{ + "description": "'measured' | 'measured_zero' (really zero) | 'not_measured' (never computed) - the two used to be indistinguishable.", + "type": "string" +} - added
Output schema / properties / sources / items / properties / coverage_pctAdded value: +{ + "description": "Share of the corpus this lane reaches. Read WITH coverage_basis.", + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / sources / items / properties / hit_rate / descriptionAdded value: +"PER-LANE definition, not comparable across lanes. NULL = not measurable for this lane." - changed
Output schema / properties / sources / items / properties / hit_rate / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / sources / items / properties / hit_rate_basisAdded value: +{ + "description": "'measured' | 'not_measured'.", + "type": "string" +} - added
Output schema / properties / sources / items / properties / last_event_timeAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / sources / items / properties / provenanceAdded value: +{ + "description": "'native_d1' = computed from our own tables; 'harness_tl_osint_scan' = community-sourced, corroborating only.", + "type": "string" +} - added
Output schema / properties / sources / items / properties / source / descriptionAdded value: +"Lane name (alias of source_name)." - added
Output schema / properties / sources / items / properties / source_nameAdded value: +{ + "type": "string" +} - added
Output schema / properties / sources / items / properties / unique_entitiesAdded value: +{ + "type": "integer" +} - added
Output schema / properties / sources / items / properties / updated_atAdded value: +{ + "type": "string" +} - added
Output schema / properties / stale_hoursAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / summary / properties / avg_hit_rate / descriptionAdded value: +"Averaged ONLY over lanes reporting a real hit_rate." - changed
Output schema / properties / summary / properties / avg_hit_rate / typePrevious value: -"number"New value: +[ + "string", + "null" +] - added
Output schema / properties / summary / properties / measured_zero_coverageAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / summary / properties / unmeasured_coverageAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +}
- Added
get_entity_aliases - Changed
get_entity_profile7 fields changed- added
Input schema / properties / limitAdded value: +{ + "description": "Neighbours in top_neighbors (default 20, max 100 over MCP). They are ordered by fidelity, so the rare low-fidelity edges are the ones a small limit drops.", + "type": "integer" +} - added
Output schema / properties / rarityAdded value: +{ + "additionalProperties": true, + "properties": { + "corpus_df": { + "description": "Threats mentioning this technique/IOC.", + "type": "integer" + }, + "corpus_n": { + "description": "Threats in the corpus.", + "type": "integer" + }, + "df_ratio": { + "type": [ + "number", + "null" + ] + }, + "live_df": { + "type": "integer" + }, + "source": { + "description": "graph_tech_df | graph_ioc_df (published-gen, matches the stored pmi denominators) or live_count.", + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / top_neighbors / items / additionalPropertiesAdded value: +true - added
Output schema / properties / top_neighbors / items / propertiesAdded value: +{ + "co_occurrence_count": { + "type": "integer" + }, + "edge_type": { + "type": "string" + }, + "fidelity": { + "description": "Rounded 0-100. Use pmi to separate edges that share a fidelity.", + "type": "number" + }, + "id": { + "type": "string" + }, + "marginals": { + "additionalProperties": true, + "properties": { + "N": { + "type": "integer" + }, + "c": { + "type": "integer" + }, + "df_actor": { + "type": "integer" + }, + "df_tech": { + "type": "integer" + } + }, + "type": "object" + }, + "pmi": { + "description": "NPMI edge types only (actor_technique, technique_cooccurrence).", + "type": "number" + }, + "type": { + "type": "string" + } +} - added
Output schema / properties / top_neighbors / items / typeAdded value: +"object" - added
Output schema / properties / top_neighbors_limitAdded value: +{ + "type": "integer" +} - added
Output schema / properties / top_neighbors_truncatedAdded value: +{ + "description": "True when more neighbours exist than were returned — raise `limit`.", + "type": "boolean" +}
- Added
get_flow_coverage - Added
get_flow_similar_threats - Changed
get_infrastructure_pivots7 fields changed- added
Output schema / properties / coverageAdded value: +{ + "additionalProperties": true, + "properties": { + "common_values_excluded": { + "type": "number" + }, + "curated_link_pivots": { + "type": "number" + }, + "dns_enriched": { + "type": "boolean" + }, + "ioc_rows": { + "type": "number" + }, + "ioc_values_examined": { + "type": "number" + }, + "note": { + "type": "string" + }, + "rarity_cap": { + "type": "number" + }, + "scorable_iocs": { + "type": "number" + }, + "shared_ioc_pivots": { + "type": "number" + }, + "threats_compared": { + "type": "number" + }, + "threats_touched": { + "type": "number" + }, + "truncated": { + "type": "boolean" + } + }, + "type": "object" +} - added
Output schema / properties / infrastructure_pivots / items / properties / categoryAdded value: +{ + "type": "string" +} - added
Output schema / properties / infrastructure_pivots / items / properties / confidenceAdded value: +{ + "description": "Rarity-derived (Adamic-Adar) for shared_ioc rows; hand-set for curated_link rows.", + "type": "number" +} - added
Output schema / properties / infrastructure_pivots / items / properties / ioc_typeAdded value: +{ + "type": "string" +} - added
Output schema / properties / infrastructure_pivots / items / properties / pivot_valueAdded value: +{ + "type": "string" +} - added
Output schema / properties / infrastructure_pivots / items / properties / sourceAdded value: +{ + "description": "'shared_ioc' (derived from the same indicator universe the correlation graph scores) or 'curated_link'.", + "type": "string" +} - added
Output schema / properties / infrastructure_pivots / items / properties / value_threat_countAdded value: +{ + "description": "How many threats corpus-wide carry this value — 2 is a strong pivot, 40 is commodity.", + "type": "number" +}
- Changed
get_ioc_blast_radius5 fields changed- added
Output schema / properties / coverageAdded value: +{ + "additionalProperties": true, + "properties": { + "center_is_cve": { + "type": "boolean" + }, + "depth_requested": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "ring1_from_cve_list": { + "description": "Threats reached via threats.cve_list, the authoritative CVE-to-threat mapping. Ring 1 is the UNION of the two, not either alone.", + "type": "integer" + }, + "ring1_from_ioc_rows": { + "description": "Threats reached via a threat_iocs row carrying this exact value.", + "type": "integer" + }, + "sibling_iocs_capped": { + "type": "boolean" + }, + "source": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / stats / properties / ringsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / stats / properties / sibling_iocsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / stats / properties / total_actorsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / stats / properties / total_techniquesAdded value: +{ + "type": "integer" +}
- Changed
get_landscape_briefing11 fields changed- added
Output schema / properties / briefings / items / properties / is_synthesisAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / fallback_noteAdded value: +{ + "description": "Names which date was served and which was skipped.", + "type": "string" +} - added
Output schema / properties / latest / descriptionAdded value: +"The most recent REAL synthesis (see latest_is_fallback)." - added
Output schema / properties / latest_age_hoursAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / latest_generated_atAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / latest_is_fallbackAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / latest_is_synthesisAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / narrative_okAdded value: +{ + "description": "Did the NEWEST run produce a real narrative?", + "type": "boolean" +} - added
Output schema / properties / newest_generated_atAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / page_sizeAdded value: +{ + "type": "integer" +} - added
Output schema / properties / stub_countAdded value: +{ + "type": "integer" +}
- Changed
get_malware_intelligence5 fields changed- added
Output schema / properties / membershipAdded value: +{ + "additionalProperties": true, + "properties": { + "grounded": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "title_match": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "type": "object" +} - added
Output schema / properties / prevalence / properties / actor_count / descriptionAdded value: +"TRUE distinct-actor prevalence, uncapped. The actors[] array is clipped to 20 — compare with actors_returned." - added
Output schema / properties / prevalence / properties / actors_returnedAdded value: +{ + "type": "integer" +} - added
Output schema / properties / prevalence / properties / threat_count_is_floorAdded value: +{ + "description": "True when the membership fetch saturated, so threat_count under-counts.", + "type": "boolean" +} - added
Output schema / properties / threats / items / properties / matched_viaAdded value: +{ + "description": "campaigns only: grounded | title | grounded+title", + "type": "string" +}
- Changed
get_mitre_gap_analysis19 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max techniques (default 20, max 100)"New value: +"Max techniques (default 20, max 100). Rows come back debt_score-descending, so limit=N is the top-N worst." - changed
Input schema / properties / tactic / descriptionPrevious value: -"Filter to one ATT&CK tactic (e.g. \"execution\")"New value: +"Filter to one ATT&CK tactic (e.g. \"execution\", \"defense-evasion\", \"command-and-control\"). An unmatched value returns summary.available_tactics." - added
Output schema / properties / summary / properties / available_tacticsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / summary / properties / by_priorityAdded value: +{ + "additionalProperties": true, + "properties": {}, + "type": "object" +} - added
Output schema / properties / summary / properties / by_tacticAdded value: +{ + "additionalProperties": true, + "properties": {}, + "type": "object" +} - added
Output schema / properties / summary / properties / corpus_totalAdded value: +{ + "type": "integer" +} - added
Output schema / properties / summary / properties / has_moreAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / summary / properties / returnedAdded value: +{ + "type": "integer" +} - added
Output schema / properties / summary / properties / scoringAdded value: +{ + "description": "States what debt_score counts.", + "type": "string" +} - added
Output schema / properties / summary / properties / tactic_filterAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / summary / properties / total / descriptionAdded value: +"Techniques matching the tactic filter (the ranking denominator), not the page size." - added
Output schema / properties / techniques / items / properties / debt_score / descriptionAdded value: +"Ranking unit. Higher = weaker coverage against more exposure; see summary.scoring." - added
Output schema / properties / techniques / items / properties / detection_countAdded value: +{ + "description": "Rules mapping this technique or its parent — NOT detections on threats that merely share it.", + "type": "integer" +} - added
Output schema / properties / techniques / items / properties / epss_maxAdded value: +{ + "type": "number" +} - added
Output schema / properties / techniques / items / properties / is_covered / descriptionAdded value: +"True when at least one detection maps this technique (or its parent) in detections.mitre_mapping." - added
Output schema / properties / techniques / items / properties / kev_exposureAdded value: +{ + "type": "integer" +} - added
Output schema / properties / techniques / items / properties / priority_label / descriptionAdded value: +"critical | high | medium | low, banded off debt_score." - added
Output schema / properties / techniques / items / properties / technique_id / descriptionAdded value: +"Pass to get_mitre_technique." - added
Output schema / properties / techniques / items / properties / threat_exposureAdded value: +{ + "type": "integer" +}
- Changed
get_mitre_technique16 fields changed- added
Input schema / properties / include_threatsAdded value: +{ + "description": "Set false to return the technique definition WITHOUT the threat list (default true). Use this when you only need the name/tactic/mitigations.", + "type": "boolean" +} - added
Input schema / properties / limitAdded value: +{ + "description": "Max threats to return (default 50, max 500)", + "type": "number" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "Threat-list row offset for paging (default 0)", + "type": "number" +} - added
Output schema / properties / deprecatedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / detail_hintAdded value: +{ + "type": "string" +} - added
Output schema / properties / matrixAdded value: +{ + "type": "string" +} - added
Output schema / properties / parent_techniqueAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / revokedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / revoked_byAdded value: +{ + "description": "Successor technique id when this one was retired — query that id instead.", + "type": "string" +} - added
Output schema / properties / sourceAdded value: +{ + "description": "'attack_catalog' (authoritative) | 'threat_mitre_fallback' | 'unknown'.", + "type": "string" +} - added
Output schema / properties / tacticsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / threat_countAdded value: +{ + "description": "TOTAL threats using this technique — compare against threats_returned to see whether the list is a page.", + "type": "integer" +} - added
Output schema / properties / threats_has_moreAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / threats_offsetAdded value: +{ + "type": "integer" +} - added
Output schema / properties / threats_omittedAdded value: +{ + "description": "Present and true when include_threats=false suppressed the list.", + "type": "boolean" +} - added
Output schema / properties / threats_returnedAdded value: +{ + "type": "integer" +}
- Changed
get_roadmap7 fields changed- added
Output schema / properties / as_ofAdded value: +{ + "description": "Last date the roadmap table itself was edited.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / countsAdded value: +{ + "additionalProperties": true, + "properties": { + "completed": { + "type": "integer" + }, + "ideas": { + "type": "integer" + }, + "in_progress": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "type": "object" +} - added
Output schema / properties / generated_atAdded value: +{ + "description": "When this response was produced.", + "type": "string" +} - added
Output schema / properties / in_progressAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / staleAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / stale_daysAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / warningAdded value: +{ + "description": "Present when stale; says the statuses are unreconciled.", + "type": "string" +}
- Changed
get_similar_threats2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (default 10, max 50)"New value: +"Max results (default 10, max 20 — the handler caps here)." - added
Output schema / properties / countsAdded value: +{ + "additionalProperties": true, + "properties": { + "has_more": { + "type": "boolean" + }, + "limit": { + "type": "integer" + }, + "matched": { + "type": "integer" + }, + "matched_is_floor": { + "description": "True when the source queries saturated, so `matched` under-counts.", + "type": "boolean" + }, + "returned": { + "type": "integer" + } + }, + "type": "object" +}
- Changed
get_technique_rules9 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Default 50, max 200."New value: +"Default 50, max 100." - added
Output schema / properties / rules / items / properties / technique_a / descriptionAdded value: +"Pass to get_mitre_technique." - added
Output schema / properties / rules / items / properties / technique_a_nameAdded value: +{ + "description": "ATT&CK name for technique_a (null if the catalog does not know the id).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / rules / items / properties / technique_b / descriptionAdded value: +"Pass to get_mitre_technique." - added
Output schema / properties / rules / items / properties / technique_b_nameAdded value: +{ + "description": "ATT&CK name for technique_b (null if the catalog does not know the id).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / summary / properties / has_moreAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / summary / properties / returnedAdded value: +{ + "type": "integer" +} - added
Output schema / properties / summary / properties / total / descriptionAdded value: +"Rules on THIS page (legacy field — use total_rules for the corpus count)." - added
Output schema / properties / summary / properties / total_rulesAdded value: +{ + "type": "integer" +}
- Changed
get_threat8 fields changed- added
Input schema / properties / max_descriptionAdded value: +{ + "description": "Char budget for the narrative description. Default 1500; 0 drops it; -1 returns it whole.", + "type": "number" +} - added
Input schema / properties / sectionsAdded value: +{ + "description": "CSV of sections to return. Any of: overview, attribution, mitre, iocs, detections (WITH rule bodies), detections_meta (roster only, the default), timeline, tags, targets, remediation, references (full bibliography), references_compact (ranked primary-first + corroboration summary, in the default), similar, updates, osint, flow, entities — or \"all\", or \"row\" (exclusive: a ~500-byte identity row plus section counts). Default: overview,attribution,mitre,iocs,detections_meta,timeline,tags,targets,similar,flow,osint,references_compact", + "type": "string" +} - added
Output schema / properties / _sectionsAdded value: +{ + "additionalProperties": true, + "properties": { + "available": { + "items": { + "type": "string" + }, + "type": "array" + }, + "ignored_unknown": { + "items": { + "type": "string" + }, + "type": "array" + }, + "note": { + "type": "string" + }, + "omitted": { + "items": { + "description": "Sections deliberately left out — re-call with sections=<name> to fetch them.", + "type": "string" + }, + "type": "array" + }, + "returned": { + "items": { + "description": "Sections present in THIS response.", + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +} - added
Output schema / properties / description_charsAdded value: +{ + "description": "True length of description when it was trimmed to max_description.", + "type": "integer" +} - added
Output schema / properties / description_truncatedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / references / descriptionAdded value: +"Full bibliography. Present only under sections=references or sections=all." - added
Output schema / properties / references_compactAdded value: +{ + "description": "Ranked primary-first, capped at 8. Present in the DEFAULT projection and in both bundles.", + "items": { + "additionalProperties": true, + "properties": { + "tier": { + "description": "primary | research | secondary", + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / references_summaryAdded value: +{ + "additionalProperties": true, + "properties": { + "earliest_source_date": { + "type": [ + "string", + "null" + ] + }, + "independent_domains": { + "description": "Distinct registrable domains across ALL references — the corroboration count. Deliberately under-counted.", + "type": "integer" + }, + "latest_source_date": { + "type": [ + "string", + "null" + ] + }, + "omitted": { + "type": "integer" + }, + "primary_count": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "type": "object" +}
- Changed
get_threat_bundle1 field changed- added
Input schema / properties / simulation_limitAdded value: +{ + "description": "Playbooks to embed, 1-20 (default 3). Each carries full command text; raise only if you need more than the newest few.", + "type": "integer" +}
- Changed
get_threat_enrichment1 field changed- added
Output schema / properties / coverageAdded value: +{ + "additionalProperties": true, + "properties": { + "atlas": { + "type": "string" + }, + "campaigns": { + "type": "string" + }, + "malware": { + "type": "string" + }, + "note": { + "type": "string" + }, + "operating_systems": { + "type": "string" + }, + "regions": { + "description": "grounded | threat_record | unmapped", + "type": "string" + }, + "sectors": { + "description": "grounded | threat_record | unmapped", + "type": "string" + }, + "tools": { + "type": "string" + } + }, + "type": "object" +}
- Changed
get_threat_hunting_bundle16 fields changed- added
Input schema / properties / pivot_limitAdded value: +{ + "description": "Infrastructure pivots to embed, 1-200 (default 25). One threat can carry 150+; get_infrastructure_pivots returns the full set.", + "type": "integer" +} - added
Input schema / properties / shapeAdded value: +{ + "description": "\"v1\" (default, unchanged nested envelope) | \"canonical\" (flat, stably-named, SMALLER — recommended for programmatic consumers) | \"both\". In canonical: technique ids are a top-level `ttps` array, sectors/regions use ONE spelling, and every array key is ALWAYS an array (never null, never an object). In v1, `similar_threats` and `infrastructure_pivots` are handler envelopes (objects) while `threat.similar_threats` is a flat array — if you are writing a parser, use canonical.", + "type": "string" +} - added
Input schema / properties / simulation_limitAdded value: +{ + "description": "Playbooks to embed, 1-20 (default 3).", + "type": "integer" +} - added
Output schema / properties / _envelopeAdded value: +{ + "description": "Shape manifest — announces that shape=\"canonical\" exists.", + "type": "object" +} - added
Output schema / properties / _shapeAdded value: +{ + "type": "object" +} - added
Output schema / properties / canonicalAdded value: +{ + "description": "Present only under shape=\"both\".", + "type": "object" +} - added
Output schema / properties / countsAdded value: +{ + "description": "canonical: a denominator for every array key.", + "type": "object" +} - added
Output schema / properties / infrastructure_pivots / descriptionAdded value: +"v1: handler envelope {threat_id, infrastructure_pivots[], coverage{}} — an OBJECT." - added
Output schema / properties / iocsAdded value: +{ + "description": "canonical: FLAT array. (In v1 this is an object keyed by category under threat.iocs.)", + "items": { + "additionalProperties": true, + "properties": { + "category": { + "type": "string" + }, + "type": { + "type": [ + "string", + "null" + ] + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / regionsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / sectorsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / similar_threats / descriptionAdded value: +"v1: handler envelope {source_threat_id, count, similar[]} — an OBJECT, not an array." - added
Output schema / properties / threat_idAdded value: +{ + "type": "string" +} - added
Output schema / properties / ttp_detailsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "tactic": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / ttpsAdded value: +{ + "description": "Canonical MITRE technique ids, present in BOTH shapes.", + "items": { + "type": "string" + }, + "type": "array" +} - removed
Output schema / requiredRemoved value: -[ - "threat" -]
- Changed
get_threat_simulations11 fields changed- added
Input schema / properties / limitAdded value: +{ + "description": "Max playbooks to return (max 50). Omit for all — bodies are large.", + "type": "number" +} - added
Input schema / properties / platformAdded value: +{ + "description": "Return only this platform: windows, linux, python (also aws, macos, multi on a few rows). Omit for all.", + "type": "string" +} - added
Output schema / properties / available_platformsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / caveatAdded value: +{ + "description": "Why these do not prove your detections fire.", + "type": "string" +} - added
Output schema / properties / deprecatedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / generation_stoppedAdded value: +{ + "description": "Date generation stopped (2026-08-03).", + "type": "string" +} - added
Output schema / properties / matchedAdded value: +{ + "type": "integer" +} - added
Output schema / properties / reasonAdded value: +{ + "description": "Present only on an empty result: no_simulations_for_threat | no_simulations_for_platform.", + "type": "string" +} - added
Output schema / properties / returnedAdded value: +{ + "type": "integer" +} - added
Output schema / properties / total_simulationsAdded value: +{ + "description": "All archived playbooks for this threat, before platform/limit.", + "type": "integer" +} - added
Output schema / properties / truncatedAdded value: +{ + "type": "boolean" +}
- Changed
get_threat_transcripts3 fields changed- added
Output schema / properties / transcripts / items / additionalPropertiesAdded value: +true - added
Output schema / properties / transcripts / items / propertiesAdded value: +{ + "generated_by": { + "type": "string" + }, + "messages": { + "items": {}, + "type": "array" + }, + "phases": { + "items": {}, + "type": "array" + }, + "score": { + "description": "Pipeline quality score.", + "type": [ + "number", + "null" + ] + }, + "signals": { + "items": {}, + "type": "array" + }, + "summary": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "title": { + "type": "string" + } +} - added
Output schema / properties / transcripts / items / typeAdded value: +"object"
- Changed
get_tool_intelligence5 fields changed- added
Output schema / properties / membershipAdded value: +{ + "additionalProperties": true, + "properties": { + "grounded": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "title_match": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "type": "object" +} - added
Output schema / properties / prevalence / properties / actor_count / descriptionAdded value: +"TRUE distinct-actor prevalence, uncapped. The actors[] array is clipped to 20 — compare with actors_returned." - added
Output schema / properties / prevalence / properties / actors_returnedAdded value: +{ + "type": "integer" +} - added
Output schema / properties / prevalence / properties / threat_count_is_floorAdded value: +{ + "description": "True when the membership fetch saturated, so threat_count under-counts.", + "type": "boolean" +} - added
Output schema / properties / threats / items / properties / matched_viaAdded value: +{ + "description": "campaigns only: grounded | title | grounded+title", + "type": "string" +}
- Changed
health6 fields changed- added
Output schema / properties / catalog_hintAdded value: +{ + "type": "string" +} - added
Output schema / properties / catalog_sourceAdded value: +{ + "description": "Always 'live' here — this response came from the server, not a cached catalog.", + "type": "string" +} - added
Output schema / properties / min_recommended_clientAdded value: +{ + "type": "string" +} - added
Output schema / properties / prompt_countAdded value: +{ + "type": "integer" +} - added
Output schema / properties / tool_countAdded value: +{ + "description": "Tools the LIVE server exposes. If your client listed fewer, its catalog is stale.", + "type": "integer" +} - added
Output schema / properties / wire_versionAdded value: +{ + "description": "Negotiated MCP protocol version.", + "type": "string" +}
- Changed
hunt4 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Row cap for non-stats queries (default 50, max 150). Ignored in stats mode."New value: +"Row cap for non-stats queries (default 50, max 100). In stats mode it caps the number of GROUPS returned. Check `has_more` in the response." - added
Output schema / properties / count / descriptionAdded value: +"Rows RETURNED, not rows matched." - added
Output schema / properties / has_moreAdded value: +{ + "description": "True when rows (or, in stats mode, groups) were cut at the limit.", + "type": "boolean" +} - added
Output schema / properties / limitAdded value: +{ + "type": "integer" +}
- Changed
hunt_schema7 fields changed- added
Output schema / properties / grammar / properties / operators / items / additionalPropertiesAdded value: +true - added
Output schema / properties / grammar / properties / operators / items / propertiesAdded value: +{ + "note": { + "type": "string" + }, + "op": { + "type": "string" + } +} - changed
Output schema / properties / grammar / properties / operators / items / typePrevious value: -"string"New value: +"object" - added
Output schema / properties / grammar / properties / quotingAdded value: +{ + "description": "When a value must be quoted — read this before writing a CVE or relative-time filter.", + "type": "string" +} - added
Output schema / properties / grammar / properties / stats / properties / functions / items / additionalPropertiesAdded value: +true - added
Output schema / properties / grammar / properties / stats / properties / functions / items / propertiesAdded value: +{ + "aliases": { + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "type": "string" + }, + "note": { + "type": "string" + } +} - changed
Output schema / properties / grammar / properties / stats / properties / functions / items / typePrevious value: -"string"New value: +"object"
- Added
list_campaigns - Changed
list_debriefs13 fields changed- added
Output schema / properties / data / items / properties / daily_themeAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / ioc_breakdownAdded value: +{ + "description": "IOC counts keyed by type (network, file, infrastructure, …).", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / data / items / properties / ioc_totalAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / data / items / properties / mitre_technique_countAdded value: +{ + "type": "integer" +} - added
Output schema / properties / data / items / properties / mitre_techniques_sampleAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / data / items / properties / new_detectionsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / data / items / properties / new_threatsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / data / items / properties / severity_countsAdded value: +{ + "type": [ + "object", + "null" + ] +} - removed
Output schema / properties / data / items / properties / titleRemoved value: -{ - "type": "string" -} - added
Output schema / properties / data / items / properties / top_actorsAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / data / items / properties / top_categoriesAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / data / items / properties / total_threatsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / data / items / properties / updated_threatsAdded value: +{ + "type": "integer" +}
- Changed
list_simulations13 fields changed- added
Input schema / properties / include_facetsAdded value: +{ + "description": "Include the corpus filter vocabulary (filter_meta). Default false — it is ~20 KB and does not shrink with limit.", + "type": "boolean" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (default 50, max 200)"New value: +"Max threats in this page (default 50, max 200)" - added
Input schema / properties / offsetAdded value: +{ + "description": "Row offset for paging (default 0). Use next_offset from the previous response.", + "type": "number" +} - added
Output schema / properties / correlation / properties / computed_over_threatsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / correlation / properties / scopeAdded value: +{ + "type": "string" +} - added
Output schema / properties / deprecatedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / generation_stoppedAdded value: +{ + "type": "string" +} - added
Output schema / properties / has_moreAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / next_offsetAdded value: +{ + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / page_simulationsAdded value: +{ + "description": "Simulation rows across the returned page only.", + "type": "integer" +} - added
Output schema / properties / returnedAdded value: +{ + "description": "Threats in THIS page.", + "type": "integer" +} - added
Output schema / properties / total / descriptionAdded value: +"Corpus-wide threats that have simulations." - added
Output schema / properties / total_simulations / descriptionAdded value: +"Corpus-wide simulation rows."
- Changed
predict_mitre_transitions1 field changed- added
Input schema / properties / basisAdded value: +{ + "description": "Filter by evidence basis. Default 'any' (unfiltered, byte-identical to previous behaviour). Use 'attack_flow' for authored-causality rows only.", + "enum": [ + "any", + "attack_flow", + "blended", + "mitre_canonical" + ], + "type": "string" +}
- Changed
search_actors4 fields changed- added
Output schema / properties / actors / items / properties / also_grounded_asAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / actors / items / properties / merged_fromAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / actors / items / properties / roleAdded value: +{ + "description": "primary = the corpus files at least one threat under this name. co-mention = it only ever appears alongside another actor, so it may be a mis-split label rather than an operator.", + "type": "string" +} - added
Output schema / properties / label_hygieneAdded value: +{ + "additionalProperties": true, + "properties": { + "actors": { + "type": "integer" + }, + "dropped": { + "description": "Labels rejected as comma-split sentence fragments, not adversaries.", + "type": "integer" + }, + "dropped_labels": { + "items": { + "type": "string" + }, + "type": "array" + }, + "note": { + "type": "string" + }, + "raw_labels": { + "type": "integer" + }, + "repaired": { + "description": "Labels whose truncated parenthetical was trimmed back to the name.", + "type": "integer" + } + }, + "type": "object" +}
86 tool updates
v8.1.1- Changed
bulk_get_cves2 fields changed- changed
Input schema / properties / cve_ids / descriptionPrevious value: -"Array of CVE IDs (max 20)"New value: +"CVE IDs (max 20)" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "cves": { + "items": { + "additionalProperties": true, + "properties": { + "cve_id": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "missing": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "cves", + "missing" + ], + "type": "object" +}
- Added
bulk_get_threats - Removed
enrich_iocs - Added
explain_correlation - Added
export_attack_navigator - Added
export_detection - Added
export_stix - Changed
generate_c2_blocklist4 fields changed- removed
Input schema / properties / formatRemoved value: -{ - "description": "Output format (default: cidr JSON)", - "enum": [ - "cidr", - "hosts", - "plain" - ], - "type": "string" -} - removed
Input schema / properties / frameworkRemoved value: -{ - "description": "Filter by C2 framework (e.g. 'cobalt-strike', 'sliver', 'havoc')", - "type": "string" -} - removed
Input schema / properties / since_daysRemoved value: -{ - "description": "How many days back to include (default 30, max 365)", - "type": "number" -} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "cidrs": { + "items": { + "type": "string" + }, + "type": "array" + }, + "count": { + "type": "integer" + }, + "detail": { + "items": { + "additionalProperties": true, + "properties": { + "asn": { + "type": "string" + }, + "country": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "last_seen": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "generated_at": { + "type": "string" + }, + "since_days": { + "type": "integer" + } + }, + "required": [ + "count" + ], + "type": "object" +}
- Added
get_actor - Changed
get_actor_intelligence7 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Actor name or canonical alias"New value: +"Threat-actor name or alias (e.g. \"APT29\")" - added
Output schema / properties / actorAdded value: +{ + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / cross_actor_attributionAdded value: +{ + "description": "Shared entities across actors, or null when the attribution engine has nothing.", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / cvesAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / mitreAdded value: +{ + "additionalProperties": true, + "properties": {}, + "type": "object" +} - added
Output schema / properties / threatsAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / toolsAdded value: +{ + "items": {}, + "type": "array" +}
- Removed
get_actor_profile - Added
get_attribution_coverage - Added
get_attribution_evidence - Added
get_c2 - Removed
get_c2_configs - Removed
get_c2_cross_correlations - Added
get_c2_dns_intel - Removed
get_c2_operators - Removed
get_c2_stats - Removed
get_c2_timeline - Removed
get_c2_watermarks - Changed
get_campaign_intelligence1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "actors": { + "items": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "canonical": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "matched": { + "type": "boolean" + }, + "prevalence": { + "additionalProperties": true, + "properties": { + "actor_count": { + "type": "integer" + }, + "threat_count": { + "type": "integer" + } + }, + "type": "object" + }, + "query": { + "type": "string" + }, + "threats": { + "items": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "top_techniques": { + "items": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "technique_id": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "matched" + ], + "type": "object" +}
- Changed
get_changelog2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max entries (default 20)"New value: +"Max entries (default 20, max 100)" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "result": { + "items": { + "additionalProperties": true, + "properties": { + "changes": { + "items": {}, + "type": "array" + }, + "id": {} + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Added
get_community_campaigns - Removed
get_correlation_engine - Added
get_correlation_path - Added
get_correlation_subgraph - Added
get_correlations - Removed
get_correlations_overview - Added
get_cve - Removed
get_cve_details - Changed
get_cve_intelligence4 fields changed- changed
Input schema / properties / cve_id / descriptionPrevious value: -"CVE ID (e.g. CVE-2025-12345)"New value: +"CVE identifier (e.g. CVE-2024-3400)" - added
Output schema / properties / cveAdded value: +{ + "additionalProperties": true, + "properties": { + "cve_id": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / related_detectionsAdded value: +{ + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / velocity_dataAdded value: +{ + "type": [ + "object", + "null" + ] +}
- Added
get_cwe - Removed
get_cwe_details - Added
get_daily_intel_bundle - Added
get_daily_theme - Added
get_debrief - Changed
get_detection_detail13 fields changed- changed
Input schema / properties / detection_id / descriptionPrevious value: -"Detection ID (e.g. 'det-001' or the detection name)"New value: +"Detection ID" - added
Output schema / properties / detection_typeAdded value: +{ + "type": "string" +} - added
Output schema / properties / false_positivesAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / id / typeAdded value: +"string" - added
Output schema / properties / kql_queryAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / mitre_mappingAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / name / typeAdded value: +"string" - added
Output schema / properties / queryAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / severityAdded value: +{ + "type": "string" +} - added
Output schema / properties / sigma_ruleAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / threat_idAdded value: +{ + "description": "Pass to get_threat.", + "type": "string" +} - added
Output schema / properties / threat_titleAdded value: +{ + "type": "string" +} - added
Output schema / requiredAdded value: +[ + "id" +]
- Changed
get_detections14 fields changed- added
Input schema / properties / cursorAdded value: +{ + "description": "Opaque pagination cursor (next_cursor from a prior result). Decoded to an offset; ignored when offset is given.", + "type": "string" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (default 50, max 200)"New value: +"Max results (default 15, max 100)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Pagination offset (default 0)"New value: +"Row offset for pagination (default 0). Or pass cursor from a prior result." - removed
Input schema / properties / searchRemoved value: -{ - "description": "Keyword search (matches detection name and description)", - "type": "string" -} - removed
Input schema / properties / severityRemoved value: -{ - "description": "Severity level filter", - "enum": [ - "critical", - "high", - "medium", - "low" - ], - "type": "string" -} - changed
Input schema / properties / type / descriptionPrevious value: -"Detection language filter"New value: +"Detection type: spl, kql, or sigma" - removed
Input schema / properties / type / enumRemoved value: -[ - "spl", - "kql", - "sigma", - "all" -] - removed
Output schema / properties / countRemoved value: -{ - "type": "number" -} - added
Output schema / properties / data / itemsAdded value: +{ + "additionalProperties": true, + "properties": { + "detection_type": { + "description": "spl | kql | sigma", + "type": "string" + }, + "id": { + "description": "Detection ID — pass to get_detection_detail / export_detection.", + "type": "string" + }, + "name": { + "type": "string" + }, + "severity": { + "type": "string" + }, + "threat_id": { + "description": "Owning threat — pass to get_threat.", + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / has_more / descriptionAdded value: +"True when another page may exist." - added
Output schema / properties / next_cursorAdded value: +{ + "description": "Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.", + "type": [ + "string", + "null" + ] +} - removed
Output schema / properties / next_offsetRemoved value: -{ - "type": [ - "number", - "null" - ] -} - added
Output schema / properties / totalAdded value: +{ + "description": "Total matching rows, when the handler reports one.", + "type": "integer" +} - added
Output schema / requiredAdded value: +[ + "data" +]
- Added
get_engine_status - Changed
get_enrichment_overview2 fields changed- added
Output schema / properties / sourcesAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "hit_rate": { + "type": "number" + }, + "source": { + "type": "string" + }, + "total_events": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "properties": { + "avg_hit_rate": { + "type": "number" + }, + "total_events": { + "type": "integer" + }, + "total_sources": { + "type": "integer" + } + }, + "type": "object" +}
- Added
get_entity_profile - Added
get_graph_campaigns - Added
get_infrastructure_pivots - Added
get_ioc_blast_radius - Changed
get_ioc_dns4 fields changed- removed
Input schema / properties / ioc_valueRemoved value: -{ - "description": "IOC value to look up (IP address, domain, or URL)", - "type": "string" -} - added
Input schema / properties / valueAdded value: +{ + "description": "IP address or domain (stored DNS enrichment lookup)", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "ioc_value" -]New value: +[ + "value" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "cross_links": { + "items": {}, + "type": "array" + }, + "domains": { + "items": {}, + "type": "array" + }, + "query_value": { + "type": "string" + }, + "total": { + "type": "integer" + } + }, + "type": "object" +}
- Changed
get_ioc_intelligence12 fields changed- removed
Input schema / properties / ioc_valueRemoved value: -{ - "description": "IOC value (IP, domain, hash, URL)", - "type": "string" -} - added
Input schema / properties / valueAdded value: +{ + "description": "Exact indicator value (IP, domain, hash, or URL)", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "ioc_value" -]New value: +[ + "value" +] - added
Output schema / properties / consensus_scoreAdded value: +{ + "description": "Multi-feed consensus; null when no feed has seen it.", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / dns_recordsAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / infrastructure_pivotsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "confidence": { + "type": "number" + }, + "ioc_value_a": { + "type": "string" + }, + "ioc_value_b": { + "type": "string" + }, + "link_type": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / ioc_valueAdded value: +{ + "type": "string" +} - added
Output schema / properties / osintAdded value: +{ + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / threat_countAdded value: +{ + "type": "integer" +} - added
Output schema / properties / threatsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "id": { + "description": "Pass to get_threat.", + "type": "string" + }, + "ioc_type": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / truncatedAdded value: +{ + "type": "boolean" +} - added
Output schema / requiredAdded value: +[ + "ioc_value" +]
- Added
get_landscape_briefing - Added
get_latest_debrief - Changed
get_malware_intelligence2 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Malware family name (e.g. LockBit, Vidar)"New value: +"Malware family name (e.g. \"LockBit\", \"Vidar\")" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "actors": { + "items": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "canonical": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "matched": { + "type": "boolean" + }, + "prevalence": { + "additionalProperties": true, + "properties": { + "actor_count": { + "type": "integer" + }, + "threat_count": { + "type": "integer" + } + }, + "type": "object" + }, + "query": { + "type": "string" + }, + "threats": { + "items": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "top_techniques": { + "items": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "technique_id": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "matched" + ], + "type": "object" +}
- Added
get_mitre_coverage - Changed
get_mitre_gap_analysis4 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (default 20, max 100)"New value: +"Max techniques (default 20, max 100)" - changed
Input schema / properties / tactic / descriptionPrevious value: -"Filter by MITRE tactic (e.g. 'initial-access', 'persistence', 'lateral-movement')"New value: +"Filter to one ATT&CK tactic (e.g. \"execution\")" - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "properties": { + "coverage_pct": { + "type": "number" + }, + "covered": { + "type": "integer" + }, + "gaps": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "type": "object" +} - added
Output schema / properties / techniquesAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "debt_score": { + "type": "number" + }, + "is_covered": { + "type": "boolean" + }, + "priority_label": { + "type": "string" + }, + "tactic": { + "type": "string" + }, + "technique_id": { + "type": "string" + }, + "technique_name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +}
- Added
get_mitre_technique - Added
get_osint - Added
get_osint_trends - Added
get_pivotal_entities - Changed
get_platform_stats10 fields changed- added
Output schema / properties / by_categoryAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / by_severityAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / top_actorsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "threat_actor": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / top_techniquesAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "technique_id": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / total_actorsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / total_correlationsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / total_detectionsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / total_iocsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / total_threatsAdded value: +{ + "type": "integer" +} - added
Output schema / properties / total_ttpsAdded value: +{ + "type": "integer" +}
- Changed
get_recent_threats10 fields changed- added
Input schema / properties / cursorAdded value: +{ + "description": "Opaque pagination cursor (next_cursor from a prior result). Decoded to an offset; ignored when offset is given.", + "type": "string" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of threats to return (default 10, max 50)"New value: +"Max results (default 15, max 100)" - added
Input schema / properties / offsetAdded value: +{ + "description": "Row offset for pagination (default 0). Or pass cursor from a prior result.", + "type": "number" +} - removed
Output schema / properties / countRemoved value: -{ - "type": "number" -} - added
Output schema / properties / dataAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "category": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "detection_count": { + "type": "integer" + }, + "id": { + "description": "Threat ID (TL-YYYY-NNNN) — pass to get_threat.", + "type": "string" + }, + "ioc_count": { + "type": "integer" + }, + "severity": { + "type": "string" + }, + "threat_actor": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / has_moreAdded value: +{ + "description": "True when another page may exist.", + "type": "boolean" +} - removed
Output schema / properties / itemsRemoved value: -{ - "type": "array" -} - added
Output schema / properties / next_cursorAdded value: +{ + "description": "Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / totalAdded value: +{ + "description": "Total matching rows, when the handler reports one.", + "type": "integer" +} - added
Output schema / requiredAdded value: +[ + "data" +]
- Changed
get_roadmap1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "completed": { + "items": {}, + "type": "array" + }, + "ideas": { + "items": {}, + "type": "array" + } + }, + "type": "object" +}
- Changed
get_similar_threats4 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Source threat ID (e.g. TL-2026-0042)", + "type": "string" +} - removed
Input schema / properties / threat_idRemoved value: -{ - "description": "Source threat ID (e.g. TL-2026-0042)", - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "threat_id" -]New value: +[ + "id" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "data": { + "items": { + "additionalProperties": true, + "properties": { + "dominance": {}, + "id": { + "description": "Neighbour threat ID — pass to get_threat.", + "type": "string" + }, + "is_high_conf_low_signal": { + "type": "boolean" + }, + "is_stale": { + "type": "boolean" + }, + "score_breakdown": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "shared_cves": { + "items": { + "type": "string" + }, + "type": "array" + }, + "shared_iocs": { + "items": {}, + "type": "array" + }, + "shared_techniques": { + "items": { + "type": "string" + }, + "type": "array" + }, + "signal_count": { + "type": "integer" + }, + "similarity_score": { + "type": "number" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "similar": { + "items": {}, + "type": "array" + }, + "source_threat_id": { + "type": "string" + } + }, + "type": "object" +}
- Added
get_started - Added
get_technique_rules - Changed
get_threat20 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Threat ID (e.g. TL-2026-0042)", + "type": "string" +} - removed
Input schema / properties / threat_idRemoved value: -{ - "description": "Threat ID (e.g., TL-2026-0042)", - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "threat_id" -]New value: +[ + "id" +] - added
Output schema / properties / attributionAdded value: +{ + "additionalProperties": true, + "properties": { + "confidence": { + "type": "string" + }, + "motivation": { + "type": "string" + }, + "nation_state": { + "type": "string" + }, + "threat_actor": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / categoryAdded value: +{ + "type": "string" +} - added
Output schema / properties / created_atAdded value: +{ + "type": "string" +} - added
Output schema / properties / descriptionAdded value: +{ + "type": "string" +} - added
Output schema / properties / detectionsAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "detection_type": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / id / descriptionAdded value: +"Threat ID (TL-YYYY-NNNN)." - added
Output schema / properties / identifiersAdded value: +{ + "additionalProperties": true, + "properties": { + "aliases": { + "items": { + "type": "string" + }, + "type": "array" + }, + "cve": { + "items": { + "type": "string" + }, + "type": "array" + }, + "cwe": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +} - added
Output schema / properties / iocsAdded value: +{ + "additionalProperties": true, + "properties": {}, + "type": "object" +} - added
Output schema / properties / mitre_attackAdded value: +{ + "items": { + "additionalProperties": true, + "properties": { + "tactic": { + "type": "string" + }, + "technique": { + "type": "string" + }, + "technique_id": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / osintAdded value: +{ + "description": "Community-OSINT summary; null below Red tier or when unscanned.", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / referencesAdded value: +{ + "items": {}, + "type": "array" +} - added
Output schema / properties / severityAdded value: +{ + "additionalProperties": true, + "properties": { + "cvss": { + "type": "number" + }, + "level": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / statusAdded value: +{ + "type": "string" +} - added
Output schema / properties / summaryAdded value: +{ + "type": "string" +} - added
Output schema / properties / tagsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / updated_atAdded value: +{ + "type": "string" +} - added
Output schema / requiredAdded value: +[ + "id" +]
- Changed
get_threat_bundle4 fields changed- changed
Input schema / properties / include / descriptionPrevious value: -"Response detail level: 'full' (default) or 'summary' (id, title, severity, MITRE only)"New value: +"\"full\" (default) bundles simulations + transcripts; \"summary\" returns just the threat" - removed
Input schema / properties / include / enumRemoved value: -[ - "full", - "summary" -] - changed
Input schema / properties / threat_id / descriptionPrevious value: -"Threat ID (e.g., TL-2026-0356)"New value: +"Threat ID (e.g. TL-2026-0042)" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "simulations": { + "type": [ + "object", + "null" + ] + }, + "threat": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "transcripts": { + "description": "Omitted entirely when include='summary'.", + "type": [ + "object", + "null" + ] + } + }, + "required": [ + "threat" + ], + "type": "object" +}
- Added
get_threat_enrichment - Changed
get_threat_hunting_bundle1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "infrastructure_pivots": { + "type": [ + "object", + "null" + ] + }, + "similar_threats": { + "type": [ + "object", + "null" + ] + }, + "simulations": { + "type": [ + "object", + "null" + ] + }, + "threat": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "threat" + ], + "type": "object" +}
- Added
get_threat_level - Added
get_threat_simulations - Changed
get_threat_transcripts2 fields changed- changed
Input schema / properties / threat_id / descriptionPrevious value: -"Threat ID to get transcripts for"New value: +"Threat ID (e.g. TL-2026-0042)" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "threat_id": { + "type": "string" + }, + "transcripts": { + "items": {}, + "type": "array" + } + }, + "required": [ + "threat_id" + ], + "type": "object" +}
- Changed
get_tool_intelligence2 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Tool name (e.g. Cobalt Strike, Mimikatz)"New value: +"Tool name (e.g. \"Cobalt Strike\", \"Mimikatz\")" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "actors": { + "items": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "canonical": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "matched": { + "type": "boolean" + }, + "prevalence": { + "additionalProperties": true, + "properties": { + "actor_count": { + "type": "integer" + }, + "threat_count": { + "type": "integer" + } + }, + "type": "object" + }, + "query": { + "type": "string" + }, + "threats": { + "items": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "top_techniques": { + "items": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "technique_id": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "matched" + ], + "type": "object" +}
- Changed
health7 fields changed- added
Output schema / properties / api_reachableAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / latest_debrief_dateAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / platform_statsAdded value: +{ + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / server_versionAdded value: +{ + "type": "string" +} - added
Output schema / properties / status / descriptionAdded value: +"'ok' | 'degraded'" - removed
Output schema / properties / versionRemoved value: -{ - "type": "string" -} - added
Output schema / requiredAdded value: +[ + "status" +]
- Added
hunt - Added
hunt_schema - Added
list_debriefs - Changed
list_simulations2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max threats to return (default 50)"New value: +"Max results (default 50, max 200)" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "correlation": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "filter_meta": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "threats": { + "items": {}, + "type": "array" + }, + "total": { + "type": "integer" + }, + "total_simulations": { + "type": "integer" + } + }, + "type": "object" +}
- Added
list_threat_categories - Removed
predict_attack_path - Added
predict_mitre_transitions - Changed
resolve_entity1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "canonical": { + "description": "Canonical name — feed to get_actor / get_malware_intelligence / get_tool_intelligence.", + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "matched": { + "type": "boolean" + }, + "matched_via": { + "type": "string" + }, + "query": { + "type": "string" + }, + "uuid": { + "type": "string" + } + }, + "required": [ + "query", + "matched" + ], + "type": "object" +}
- Changed
search_actors8 fields changed- removed
Input schema / properties / limitRemoved value: -{ - "description": "Max results (default 20)", - "type": "number" -} - changed
Input schema / properties / malware / descriptionPrevious value: -"Only actors with a threat deploying this malware family (e.g. 'LockBit')"New value: +"Only actors with a threat deploying this malware family (e.g. \"LockBit\")" - removed
Input schema / properties / motivationRemoved value: -{ - "description": "Filter by motivation (e.g. 'financial', 'espionage', 'destruction')", - "type": "string" -} - removed
Input schema / properties / nation_stateRemoved value: -{ - "description": "Filter by nation-state (e.g. 'Russia', 'China', 'Iran')", - "type": "string" -} - removed
Input schema / properties / queryRemoved value: -{ - "description": "Search term (actor name or alias)", - "type": "string" -} - changed
Input schema / properties / sector / descriptionPrevious value: -"Only actors with a threat targeting this sector (e.g. 'Healthcare')"New value: +"Only actors with a threat targeting this sector (e.g. \"Healthcare\")" - changed
Input schema / properties / tool / descriptionPrevious value: -"Only actors with a threat using this tool (e.g. 'Cobalt Strike')"New value: +"Only actors with a threat using this tool (e.g. \"Cobalt Strike\")" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "actors": { + "items": { + "additionalProperties": true, + "properties": { + "motivation": { + "type": "string" + }, + "name": { + "description": "Canonical actor name — pass to get_actor.", + "type": "string" + }, + "nation_state": { + "type": "string" + }, + "threat_count": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "has_more": { + "description": "True when another page may exist.", + "type": "boolean" + }, + "next_cursor": { + "description": "Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.", + "type": [ + "string", + "null" + ] + }, + "total": { + "description": "Total matching rows, when the handler reports one.", + "type": "integer" + } + }, + "type": "object" +}
- Added
search_corpus_semantic - Changed
search_detections12 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max results per page (default 25, max 200)."New value: +"Max results (default 25, max 200)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Pagination offset (0-based). Pass next_offset from the previous response to page through results."New value: +"Row offset for pagination (default 0)" - changed
Input schema / properties / query / descriptionPrevious value: -"Search term (matches detection name and description)"New value: +"Search term (rule text, CVE, technique, etc.)" - changed
Input schema / properties / severity / descriptionPrevious value: -"Severity level filter"New value: +"Filter by severity: critical, high, medium, low" - removed
Input schema / properties / severity / enumRemoved value: -[ - "critical", - "high", - "medium", - "low" -] - changed
Input schema / properties / type / descriptionPrevious value: -"Detection language filter"New value: +"Detection type: spl, kql, or sigma" - removed
Input schema / properties / type / enumRemoved value: -[ - "spl", - "kql", - "sigma", - "all" -] - removed
Output schema / properties / countRemoved value: -{ - "type": "number" -} - added
Output schema / properties / data / itemsAdded value: +{ + "additionalProperties": true, + "properties": { + "detection_type": { + "description": "spl | kql | sigma", + "type": "string" + }, + "id": { + "description": "Detection ID — pass to get_detection_detail / export_detection.", + "type": "string" + }, + "name": { + "type": "string" + }, + "severity": { + "type": "string" + }, + "threat_id": { + "description": "Owning threat — pass to get_threat.", + "type": "string" + } + }, + "type": "object" +} - removed
Output schema / properties / has_moreRemoved value: -{ - "type": "boolean" -} - removed
Output schema / properties / next_offsetRemoved value: -{ - "type": [ - "number", - "null" - ] -} - added
Output schema / requiredAdded value: +[ + "data" +]
- Changed
search_iocs7 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (default 50)"New value: +"Max results (default 25, max 100)" - removed
Input schema / properties / queryRemoved value: -{ - "description": "IOC value to search (IP, domain, hash, URL, or keyword)", - "type": "string" -} - changed
Input schema / properties / type / descriptionPrevious value: -"IOC type filter"New value: +"IOC category (e.g. network, file, behavioral)" - removed
Input schema / properties / type / enumRemoved value: -[ - "ip", - "domain", - "hash", - "url", - "network", - "file", - "behavioral", - "all" -] - added
Input schema / properties / valueAdded value: +{ + "description": "Substring to match against IOC values", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "query" -] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "data": { + "items": { + "additionalProperties": true, + "properties": { + "category": { + "type": "string" + }, + "ioc_type": { + "type": "string" + }, + "threat_id": { + "description": "Owning threat — pass to get_threat.", + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "has_more": { + "description": "True when another page may exist.", + "type": "boolean" + }, + "next_cursor": { + "description": "Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.", + "type": [ + "string", + "null" + ] + }, + "total": { + "description": "Total matching rows, when the handler reports one.", + "type": "integer" + } + }, + "required": [ + "data" + ], + "type": "object" +}
- Added
search_threats - Added
search_vulnerabilities - Added
search_xscan_indicators
41 tool updates
v0.1.0- First observed
bulk_get_cves - First observed
enrich_iocs - First observed
generate_c2_blocklist - First observed
get_actor_intelligence - First observed
get_actor_profile - First observed
get_c2_configs - First observed
get_c2_cross_correlations - First observed
get_c2_operators - First observed
get_c2_stats - First observed
get_c2_timeline - First observed
get_c2_watermarks - First observed
get_campaign_intelligence - First observed
get_changelog - First observed
get_correlation_engine - First observed
get_correlations_overview - First observed
get_cve_details - First observed
get_cve_intelligence - First observed
get_cwe_details - First observed
get_detection_detail - First observed
get_detections - First observed
get_enrichment_overview - First observed
get_ioc_dns - First observed
get_ioc_intelligence - First observed
get_malware_intelligence - First observed
get_mitre_gap_analysis - First observed
get_platform_stats - First observed
get_recent_threats - First observed
get_roadmap - First observed
get_similar_threats - First observed
get_threat - First observed
get_threat_bundle - First observed
get_threat_hunting_bundle - First observed
get_threat_transcripts - First observed
get_tool_intelligence - First observed
health - First observed
list_simulations - First observed
predict_attack_path - First observed
resolve_entity - First observed
search_actors - First observed
search_detections - First observed
search_iocs
TDQS
The descriptions are unusually thorough, but the set is dense with overlapping families: get_threat / get_threat_enrichment / get_threat_bundle / get_threat_hunting_bundle, get_cve / get_cve_intelligence, get_actor / get_actor_intelligence, get_ioc_intelligence / get_entity_profile, and the multiple campaign tools. An agent can easily pick a differently-scoped variant and get a different result shape than expected. The detailed caveats are the only thing keeping this from a 1.
The overwhelming majority of tool names follow a clear verb_noun snake_case pattern: get_threat, search_threats, list_debriefs, export_stix, generate_c2_blocklist, explain_correlation, and hunt_schema. Minor deviations like `health` and bare `hunt`, plus the alternation between get/search on very similar resources, keep it from a perfect 5.
81 tools is far beyond a workable MCP surface; the list itself becomes the main cognitive burden for an agent. The many get_*_intelligence and bundle tools show the platform knows fragmentation is a problem, but they add to rather than reduce the raw count.
The threat-intelligence domain is covered remarkably well: threats, actors, malware, tools, campaigns, CVEs, CWEs, IOCs, detections, C2, MITRE, ATT&CK Flows, and correlation evidence all have dedicated lookup and search paths. There are only minor workaroundable gaps such as some endpoints without full pagination and some stored-only enrichment layers.
Maintenance
Related MCP Connectors
Enrich, search, assess, and manage threat intelligence through 80+ typed MCP tools.
Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Security-first WordPress MCP server. 129 tools for Claude, ChatGPT, Gemini. Free on wp.org.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceAn MCP server that exposes a 60+ tool security and threat-intel stack to AI agents, enabling secret scanning, Sigma rule generation, ransomware lookup, OSINT, and deep research.1MIT
- FlicenseNot gradedqualityCmaintenanceThis MCP server connects Claude Desktop to OpenCTI for AI-augmented threat intelligence analysis, enabling natural language queries and instant, contextualized answers from your threat intelligence database.29-
- AlicenseNot gradedqualityDmaintenanceA comprehensive MCP server that exposes multiple OSINT tools to AI assistants like Claude, enabling sophisticated reconnaissance and information gathering tasks using industry-standard OSINT tools.237MIT
- AlicenseNot gradedqualityDmaintenanceUnifies 7,283+ detection rules from Sigma, Splunk ESCU, Elastic, and KQL into a single queryable interface via MCP, with a web dashboard and autonomous agent pipeline for detection engineering.1911Apache 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/threadlinqs-cmd/intelthreadlinqs-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server