Skip to main content
Glama
threadlinqs-cmd

Intel Threadlinqs MCP

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.

npm version Node License: MIT

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-mcp

Claude Code

claude mcp add threadlinqs-intel \
  -e THREADLINQS_API_KEY=tl_your_key_here \
  -- npx -y intelthreadlinqs-mcp

The -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.

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

orient

Start here — catalog, corpus shape, categories, TLQL grammar

triage_cve

CVE end-to-end: severity, exploitation, exposure, remediation

profile_actor

Actor dossier: TTPs, targeting, attribution confidence

hunt_ioc

Indicator → linked threats, blast radius, blocking action

hunt_corpus

Aggregate questions in TLQL over the hunt index

research_question

Open-ended research via semantic corpus search

map_detections_to_mitre

Map a threat's SPL/KQL/Sigma to ATT&CK, flag gaps

review_detection_gaps

Highest-value detection debt, ranked by exposure

write_detection

Draft a deployable rule grounded in corpus logic

predict_next_move

Forecast the next (or preceding) ATT&CK techniques

explain_link

Why two threats are linked, with the evidence

map_campaign

Campaign members, shared infra, pivotal entities

review_attribution

Audit whether an attribution is evidence-backed

pivot_infrastructure

Pivot across DNS, hosting and adjacent infrastructure

malware_dossier

Profile a malware family or offensive tool

build_c2_blocklist

Firewall-ready C2 blocklist with operator clustering

osint_sweep

Fold community signal in; surface coverage lead time

sweep_vulnerabilities

Triage by exploitability, not CVSS alone

plan_purple_team

Simulations paired with the detections they should trip

export_for_tooling

STIX 2.1, ATT&CK Navigator, SIEM-ready rules

bulk_enrich

Batch a list of threat/CVE ids without N round-trips

assess_exposure

Covered vs uncovered for a CVE, actor or technique

daily_brief

Today's posture, top new threats, daily theme

period_review

Review a day or span from the debrief archive

platform_status

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_KEY environment variable (Bearer token to the worker API)

  • Runtime: Node ≥18

  • SDK: @modelcontextprotocol/sdk@^1.26.0

  • Backend: 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, so tools/list returns 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:catalog after deploying the worker, since the worker owns the tool and prompt registries. npm run test:catalog fails the build when the snapshot and the live catalog disagree, and it runs on prepublishOnly.

License

MIT © Threadlinqs

Available Tools

81 tools
bulk_get_cvesBulk Get CVEsA
Read-onlyIdempotent

Fetch up to 20 enriched CVEs by ID in one call. Returns {cves, missing, count}.

ParametersJSON Schema
NameRequiredDescriptionDefault
cve_idsYesCVE IDs (max 20)

Output Schema

ParametersJSON Schema
NameRequiredDescription
cvesYes
countNo
missingYes

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 ThreatsA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
detailNo"summary" (default, all 20 fit) | "full" (whole dossiers, max 3 ids per call)
threat_idsYesThreat IDs (max 20)

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesRows actually present in threats[] — safe to iterate on.
detailNo"summary" | "full" — which row shape threats[] carries.
missingYes
threatsYes
requestedNoHow many ids the caller supplied.
detail_hintNo
deferred_idsNo
deferred_reasonNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 CorrelationA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
threat_aYesFirst threat ID.
threat_bYesSecond threat ID.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent with HTTP 404 when the engine has no edge between the pair.
is_staleNo
dominanceNo
shared_cvesNo
shared_iocsNo
signal_countNo
score_breakdownNo
shared_techniquesNo
is_high_conf_low_signalNo

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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_attack_navigatorExport ATT&CK Navigator LayerA
Read-onlyIdempotent

Export a MITRE ATT&CK Navigator layer (enterprise-attack) for visualization. Pass actor= to score techniques attributed to one actor, or all=true for platform-wide coverage. score is PER TECHNIQUE — the number of corpus threats using it (for the actor, or platform-wide) — so the heatmap ranks within a tactic, not just between tactics; the unit is stated in the layer's description and metadata. Returns {name, versions, domain, description, techniques:[{techniqueID, score, color, comment}], gradient, metadata}. Capped at 600 techniques; when the tail is dropped, metadata carries a 'truncated' entry saying so. ATLAS (AML.*) and non-enterprise ids are excluded, since the layer domain is enterprise-attack.

ParametersJSON Schema
NameRequiredDescriptionDefault
allNoIf true, build a platform-wide coverage layer from MITRE coverage instead of a single actor
actorNoThreat-actor name or alias whose techniques to score (e.g. "APT29")

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameNo
domainNo
gradientNo
metadataNo
versionsNo
techniquesYes
descriptionNoIncludes the scoring unit ("Score = …").

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds non-obvious behavioral detail beyond those: score is per technique accounting for corpus threats, ranking is within a tactic, the layer is capped at 600 techniques and may carry a 'truncated' entry, and ATLAS/non-enterprise IDs are excluded. These are important for correct interpretation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded with the primary purpose, but includes a full returned-structure list that duplicates the output schema. That sentence is slightly redundant, but otherwise every sentence earns its place and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given branch annotations and output schema exist, the description completely covers non-obvious behavioral details: the meaning of 'score', how the two modes differ, truncation behavior, exclusions, and the exact matching between parameters and use cases. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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. The description largely mirrors that information and adds only a scoring context rather than substantially enriching individual parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Export a MITRE ATT&CK Navigator layer (enterprise-attack) for visualization.' It clearly distinguishes this tool from siblings like export_stix or get_mitre_coverage by naming the exact artifact and domain scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent to 'pass actor=<name>' for actor-level coverage or 'all=true' for platform-wide coverage, which is clear usage guidance for the two parameters. It does not explicitly enumerate when not to use this tool versus neighboring export/get_mitre tools, 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.

export_detectionExport DetectionA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
formatYesspl, kql, sigma, or json
detection_idYesDetection ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
formatNo
contentNoRule text for spl/kql/sigma. For format=json the detection object is returned directly instead.
availableNo
detection_idNo

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 BundleA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
actorNoThreat-actor name or alias to export (e.g. "APT29")
cve_idNoCVE identifier to export (e.g. CVE-2024-3400)
threat_idNoThreat ID to export (e.g. TL-2026-0042)
include_osintNoAdd community `sighting` objects for corroborated indicators (default false)

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNo
typeYesAlways 'bundle'.
objectsYes

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 BlocklistA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
cidrsNo
countYes
detailNo
since_daysNo
generated_atNo

TDQS

A4.4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 ProfileA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesActor name or alias (e.g. 'APT29', 'Lazarus Group')

Output Schema

ParametersJSON Schema
NameRequiredDescription
cvesNo
actorYes
mitreNo
toolsNo
countsNo
targetsNo
threatsNo
relationshipsNo
actor_relationshipsNo
actor_relationships_coverageNoPresent only when actor_relationships is empty: says the baseline has no row, not that the actor is unrelated.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 IntelligenceA
Read-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".

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThreat-actor name or alias (e.g. "APT29")

Output Schema

ParametersJSON Schema
NameRequiredDescription
cvesNo
actorNo
mitreNo
toolsNo
threatsNo
actor_relationshipsNo
cross_actor_attributionNo

TDQS

A4.4/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 LinksA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
actorNoOptional: only rows naming this actor on either side (e.g. "Lazarus Group"). Omit to list the whole baseline.
limitNoDefault 50, max 200.
rel_typeNoOptional: filter by relationship type. The response's coverage.rel_types lists what is actually present.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
countNo
caveatYesAbsence-is-not-evidence statement. Do not drop it when summarising.
coverageYes
unrecordedNoPresent and true when an `actor` filter matched nothing. Means UNRECORDED, not "no relationships exist".
unrecorded_noteNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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)A
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax pairs per list (default 50, max 100)
min_cooccurrenceNoMinimum 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

ParametersJSON Schema
NameRequiredDescription
dataYes
noteNo
countNo
pairsNo
corpusNo
filtersNo
tag_pairsNo
tag_pair_countNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 FlowA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNo'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_idYesThreat ID (e.g. TL-2026-1916)

Output Schema

ParametersJSON Schema
NameRequiredDescription
flowNo
generatorNo'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_idYes
flow_validNo
node_countNo
flow_errorsNo
flow_warningsNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 CoverageA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
actorNoOptional — scope the `recent` list to one actor.

Output Schema

ParametersJSON Schema
NameRequiredDescription
corpusNo
engineNo
recentNo
by_scopeNo
by_reasonNo
top_actorsNo
by_confidenceNo

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 EvidenceA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
threat_idYesThreat ID (e.g. TL-2026-0989).

Output Schema

ParametersJSON Schema
NameRequiredDescription
actorNo
scopeNo
stateYes'assessed' vs 'pending_research' — whether this is a real assessment or an unresearched intake stub. Do not present a stub as an assessment.
titleNo
methodNo
signalsNo
verdictNo
evidenceNo
queued_atNo
reasoningNo
suspectedNo
threat_idYes
actor_uuidNo
confidenceNo
reason_codeNo
attributed_atNo
current_actorNo
actor_canonicalNo

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 IntelligenceA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoWhich C2 dataset to return (default 'beacons')
limitNoMax records for the record-bearing views — beacons (default 50), configs (default 25), correlations (default 25). Max 100.
offsetNoSkip this many records — 'correlations' only; the aggregate summary block stays whole across pages.

Output Schema

ParametersJSON Schema
NameRequiredDescription
asnsNo
dataNo
itemsNo
totalNo
monthsNo
beaconsNo
configsNo
clustersNo
versionsNo
countriesNo
aggregatesNo
watermarksNo
correlationsNo

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 UnmaskingA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 40, max 100.
fidelityNo
compromisedNoOnly hosts flagged as compromised rather than adversary-owned.

Output Schema

ParametersJSON Schema
NameRequiredDescription
rowsYes
statsNo
totalNo
offsetNo

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 IntelligenceA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesCampaign / operation name

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryNo
actorsNo
matchedYes
threatsNo
canonicalNo
membershipNo
prevalenceNo
entity_typeNo
top_techniquesNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 ChangelogA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax entries (default 20, max 100)

Output Schema

ParametersJSON Schema
NameRequiredDescription
countNo
staleNo
totalNo
entriesYes
warningNoPresent when the feed is stale; says what it does NOT cover.
has_moreNo
stale_daysNo
latest_entry_dateNoDate of the newest entry — the feed cut-off.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 CampaignsA
Read-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".

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 15, max 50.

Output Schema

ParametersJSON Schema
NameRequiredDescription
windowNo
campaignsNo
generated_atNo
community_errorNoSet to 'upstream_unavailable' on a proxy failure — report the feed as unavailable, NOT as zero campaigns.

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 PathA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesTarget threat ID.
fromYesStarting threat ID.
max_hopsNoSearch depth, 1-8 (default 6).

Output Schema

ParametersJSON Schema
NameRequiredDescription
toYes
fromYes
hopsNo
foundYes
reasonNoWhy no path exists (no similarity edges vs different components) when found is false.
path_strengthNo

TDQS

A4.1/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 EngineA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoPaged 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.
engineNoWhich correlation engine to read (default 'overview')
offsetNoPaged engines only: skip this many rows.

Output Schema

ParametersJSON Schema
NameRequiredDescription
cvesNo
iocsNo
enginesNo
sourcesNo
summaryNo
sync_logNo
techniquesNo
infrastructureNo
shared_entitiesNo

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 SubgraphA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
depthNoHops, 1-3 (default 1). Each hop multiplies the node count.
seed_idYesThe entity id/value to expand from.
edge_typeNoKeep only edges of this type (also prunes the traversal, so it changes which nodes are reachable). Omit for all types.
seed_typeYes
limit_edgesNoDefault 80, max 120 over MCP.
limit_nodesNoDefault 40, max 60 over MCP.
min_fidelityNoDrop 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

ParametersJSON Schema
NameRequiredDescription
seedNo
edgesNo
nodesNo
countsNo
truncatedNo
params_echoNo

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 CVEA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
cve_idYesCVE identifier (e.g. CVE-2024-3400)

Output Schema

ParametersJSON Schema
NameRequiredDescription
kevNo
epssNo
cve_idYes
cvss_v3No
enrichedNoFalse when the CVE is unknown — then only cve_id/valid/reason are present.
threat_idsNo
weaknessesNo
descriptionNo
exploitationNo
threat_countNo
published_dateNo
enrichment_noteNoPresent only on 'not_enriched'; names the seeding source.
threat_ids_noteNoPresent only when the derived cve_details.threat_ids reverse index disagreed with the live join.
affected_productsNo
enrichment_statusNo'enriched' or 'not_enriched'. On 'not_enriched' a blank CVSS/EPSS/age_days means NOT MEASURED, not measured-empty.
threat_ids_sourceNoAlways 'threats.cve_list (authoritative live join)' when the join ran.
threat_ids_derived_onlyNo
affected_products_raw_countNoEntries before pre-release CPE collapsing.

TDQS

A4.4/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 IntelligenceA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
cve_idYesCVE identifier (e.g. CVE-2024-3400)

Output Schema

ParametersJSON Schema
NameRequiredDescription
cveNo
mitreNo
actorsNo
threatsNo
related_cvesNo
velocity_dataNo
related_detectionsNo

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CWEA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
cwe_idYesCWE identifier (e.g. CWE-79)

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameNo
cwe_idYes
enrichedNoFalse when not found — then only cwe_id is present.
threat_idsNo
abstractionNo
descriptionNo
mitigationsNo
related_cvesNoCorpus CVEs mapping to this CWE (top 20, KEV then CVSS). NULL means the join could not run — it never means "none exist"; [] does.
related_cwesNo
severity_noteNo
detection_methodsNo
related_cve_countNoTrue total mapping to this CWE, which can exceed the 20 returned.
related_cves_noteNo
common_consequencesNo
likelihood_of_exploitNoMITRE's High/Medium/Low rating. CWE has NO CVSS severity — see severity_note.

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 PostureA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoRaw 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_idYesThreat ID (e.g. TL-2026-1916)

Output Schema

ParametersJSON Schema
NameRequiredDescription
countNoTOTAL technique x countermeasure pairs, not the number returned in `mappings`.
errorNoPresent only on 404 ('threat not found'). A threat that exists but has no mapping answers 200, never 404.
caveatNoStates that this is a deterministic projection of threat_mitre, not independent evidence.
reasonNoPresent only on the 200-with-zero-mappings case: says WHY there is no posture (no techniques mapped vs techniques with no countermeasure).
coverageNo
mappingsNo
threat_idYes
detail_hintNo
countermeasuresNo
mappings_returnedNo
mappings_truncatedNoTrue when `mappings` was capped; `countermeasures` still covers every pair.
countermeasure_countNo
offensive_technique_countNoDistinct ATT&CK techniques on the threat — the denominator the projection ran over.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 BundleA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoDebrief date YYYY-MM-DD (default: latest)
top_nNoHow many top threats to include (default 5, max 10)

Output Schema

ParametersJSON Schema
NameRequiredDescription
debriefNo
detail_hintNo
top_threatsNoLEAN summary rows (the search_threats shape) — call get_threat(id) for a dossier.
platform_statsNo
correlations_overviewNo

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 ThemeA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
themesNo
tags_noteNo
yesterdayNo

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 DebriefA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateYesDebrief date in YYYY-MM-DD format (e.g. 2026-05-30)

Output Schema

ParametersJSON Schema
NameRequiredDescription
dateNo
statsNo
titleNo
themesNo
summaryNo
threatsNo
highlightsNo
new_threatsNo
new_detectionsNo

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 DetailA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
detection_idYesDetection ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameNo
queryNo
severityNo
kql_queryNo
threat_idNoPass to get_threat.
sigma_ruleNo
threat_titleNo
mitre_mappingNo
detection_typeNo
false_positivesNo

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 DetectionsA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoDetection type: spl, kql, or sigma
limitNoMax results (default 15, max 100)
cursorNoOpaque pagination cursor (next_cursor from a prior result). Decoded to an offset; ignored when offset is given.
offsetNoRow offset for pagination (default 0). Or pass cursor from a prior result.
threat_idNoFilter detections for a specific threat ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
totalNoTotal matching rows, when the handler reports one.
has_moreNoTrue when another page may exist.
next_cursorNoOpaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 StatusA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
evalNo
enginesYes
failuresNo
generated_atNo
graph_pipelineNo

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 OverviewA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoStates which advertised sources are lanes and which are fields of a lane.
as_ofNoNewest row timestamp - this is a nightly snapshot, not a live read.
sourcesNo
summaryNo
stale_hoursNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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)A
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoName or alias to expand (e.g. "andariel"). Resolved exact-then-fuzzy, same ladder as resolve_entity.
typeNoOptional: actor|malware|tool|sector|region|technique|campaign — narrows name resolution.
uuidNoEntity uuid, if you already have one from resolve_entity. Skips resolution.

Output Schema

ParametersJSON Schema
NameRequiredDescription
uuidNo
caveatNoOver-merge warning. Do not drop it when summarising.
aliasesNo
clusterNo
matchedYes
canonicalNo
alias_countNo
entity_typeNo
matched_viaNouuid | exact | fuzzy
corpus_uses_separatelyNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 ProfileA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNeighbours 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_idYesThe entity id/value (TL- id, T-number, actor name, IOC value, or CVE id).
node_typeYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
cvesNo
iocsNo
nodeYes
rarityNo
threatsNo
campaignsNo
techniquesNo
top_neighborsNo
top_neighbors_limitNo
top_neighbors_truncatedNoTrue when more neighbours exist than were returned — raise `limit`.

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CoverageA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
flowsYes
channelNo
threatsYes
authoredNoFlows with generator='harness'. Only these assert causality.
flow_nodesNo
by_generatorNo
coverage_pctYesAuthored flows as a percentage of the corpus — the denominator for any flow-derived claim.
flow_transitionsNo
path_similarity_pairsNo

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 ThreatsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax neighbours (default 20, max 100)
min_scoreNoDrop neighbours below this sim_flow (0-1)
threat_idYesThreat ID (e.g. TL-2026-1916)

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
countNo
reasonNoPresent only when data is empty; distinguishes "no flow published" from "flow published, no neighbours".
threat_idYes

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CampaignsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 15, max 50.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
summaryNo

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 PivotsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
threat_idYesThreat ID (e.g. TL-2026-0042)

Output Schema

ParametersJSON Schema
NameRequiredDescription
coverageNo
dns_trailNo
threat_idYes
pivot_countNo
dns_record_countNo
infrastructure_pivotsNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 RadiusA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
depthNoTraversal rings to expand (1–3, default 3): 1=threats, 2=+techniques, 3=+actors & sibling IOCs
valueYesIndicator value (IP, domain, hash, URL, or CVE-XXXX-NNNN)

Output Schema

ParametersJSON Schema
NameRequiredDescription
ringsNo
statsNo
centerYes
coverageNo
edge_scoresNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 EnrichmentA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
valueYesIP address or domain (stored DNS enrichment lookup)

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalNo
domainsNo
cross_linksNo
query_valueNo

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 DossierA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
valueYesExact indicator value (IP, domain, hash, or URL)

Output Schema

ParametersJSON Schema
NameRequiredDescription
osintNo
threatsNo
ioc_valueYes
truncatedNo
dns_recordsNo
threat_countNo
consensus_scoreNoMulti-feed consensus; null when no feed has seen it.
infrastructure_pivotsNo

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 BriefingA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
latestNoThe most recent REAL synthesis (see latest_is_fallback).
briefingsNo
page_sizeNo
stub_countNo
top_viewedNo
narrative_okNoDid the NEWEST run produce a real narrative?
fallback_noteNoNames which date was served and which was skipped.
latest_age_hoursNo
latest_is_fallbackNo
latest_generated_atNo
latest_is_synthesisNo
newest_generated_atNo

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 DebriefA
Read-onlyIdempotent

Get the most recent daily intelligence debrief in full detail (resolves the latest date for you).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
dateNo
titleNo
latestNo
summaryNo

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 IntelligenceA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesMalware family name (e.g. "LockBit", "Vidar")

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryNo
actorsNo
matchedYes
threatsNo
canonicalNo
membershipNo
prevalenceNo
entity_typeNo
top_techniquesNo

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 CoverageB
Read-onlyIdempotent

Get MITRE ATT&CK coverage across the platform. Optionally filter by tactic.

ParametersJSON Schema
NameRequiredDescriptionDefault
tacticNoFilter by ATT&CK tactic (e.g. "initial-access")

Output Schema

ParametersJSON Schema
NameRequiredDescription
tacticsNo
top_techniquesNo
total_techniquesNo

TDQS

B3.4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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 AnalysisA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax techniques (default 20, max 100). Rows come back debt_score-descending, so limit=N is the top-N worst.
tacticNoFilter to one ATT&CK tactic (e.g. "execution", "defense-evasion", "command-and-control"). An unmatched value returns summary.available_tactics.

Output Schema

ParametersJSON Schema
NameRequiredDescription
summaryNo
techniquesNo

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 TechniqueA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax threats to return (default 50, max 500)
offsetNoThreat-list row offset for paging (default 0)
technique_idYesTechnique ID (e.g. T1059 or T1059.001)
include_threatsNoSet false to return the technique definition WITHOUT the threat list (default true). Use this when you only need the name/tactic/mitigations.

Output Schema

ParametersJSON Schema
NameRequiredDescription
matrixNo
sourceNo'attack_catalog' (authoritative) | 'threat_mitre_fallback' | 'unknown'.
tacticNo
revokedNo
tacticsNo
threatsNo
techniqueNo
deprecatedNo
revoked_byNoSuccessor technique id when this one was retired — query that id instead.
detail_hintNo
mitigationsNo
data_sourcesNo
technique_idYes
threat_countNoTOTAL threats using this technique — compare against threats_returned to see whether the list is a page.
threats_offsetNo
threats_omittedNoPresent and true when include_threats=false suppressed the list.
parent_techniqueNo
threats_has_moreNo
threats_returnedNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CorroborationA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
ioc_valueNoExact indicator (IP, domain, URL, MD5 or SHA256). Returns the community lookup + our linked threats.
threat_idNoThreat ID (e.g. TL-2026-1531). Returns the per-threat corroboration block.

Output Schema

ParametersJSON Schema
NameRequiredDescription
valueNoPresent on the per-IOC shape (ioc_value input).
scannedNo
lead_daysNoDays the community saw an indicator before our report.
reportersNo
threat_idNoPresent on the per-threat shape.
threat_idsNo
corroboratedNo
matched_tagsNo
indicator_countNo
community_seen_before_reportNo

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_pivotal_entitiesPivotal EntitiesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 25, max 100.
node_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
noteNoStates that betweenness is an ego-bridge approximation, not exact Brandes.

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 StatsA
Read-onlyIdempotent

Get aggregate platform statistics: threat, detection, IOC, MITRE technique, and actor counts.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
top_actorsNo
total_iocsNo
total_ttpsNo
by_categoryNo
by_severityNo
total_actorsNo
total_threatsNo
top_techniquesNo
total_detectionsNo
total_correlationsNo

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 ThreatsA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax results (default 15, max 100)
cursorNoOpaque pagination cursor (next_cursor from a prior result). Decoded to an offset; ignored when offset is given.
offsetNoRow offset for pagination (default 0). Or pass cursor from a prior result.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
totalNoTotal matching rows, when the handler reports one.
has_moreNoTrue when another page may exist.
next_cursorNoOpaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 RoadmapA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
as_ofNoLast date the roadmap table itself was edited.
ideasNo
staleNo
countsNo
warningNoPresent when stale; says the statuses are unreconciled.
completedNo
stale_daysNo
in_progressNo
generated_atNoWhen this response was produced.

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 ThreatsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesSource threat ID (e.g. TL-2026-0042)
limitNoMax results (default 10, max 20 — the handler caps here).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
countsNo
similarNo
source_threat_idNo

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 StartedA
Read-onlyIdempotent

Start here. Returns the Threadlinqs Intelligence tool catalog, categories, tiering, and usage guidance. No API call — read this before using other tools.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
toolsYes
serverNo
exportsNo
tieringNo
resourcesNo
categoriesNo
instructionsNo

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 RulesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 50, max 100.

Output Schema

ParametersJSON Schema
NameRequiredDescription
rulesYes
summaryNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 ThreatA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThreat ID (e.g. TL-2026-0042)
sectionsNoCSV 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_descriptionNoChar budget for the narrative description. Default 1500; 0 drops it; -1 returns it whole.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYesThreat ID (TL-YYYY-NNNN).
iocsNo
tagsNo
osintNoCommunity-OSINT summary; null below Red tier or when unscanned.
titleNo
statusNo
summaryNo
categoryNo
severityNo
_sectionsNo
created_atNo
detectionsNo
referencesNoFull bibliography. Present only under sections=references or sections=all.
updated_atNo
attributionNo
descriptionNo
identifiersNo
mitre_attackNo
description_charsNoTrue length of description when it was trimmed to max_description.
references_compactNoRanked primary-first, capped at 8. Present in the DEFAULT projection and in both bundles.
references_summaryNo
description_truncatedNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 BundleA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeNo"full" (default) bundles simulations + transcripts; "summary" returns just the threat
threat_idYesThreat ID (e.g. TL-2026-0042)
simulation_limitNoPlaybooks to embed, 1-20 (default 3). Each carries full command text; raise only if you need more than the newest few.

Output Schema

ParametersJSON Schema
NameRequiredDescription
threatYes
simulationsNo
transcriptsNoOmitted entirely when include='summary'.

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 EnrichmentA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThreat ID (e.g. TL-2026-0042)

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
atlasNo
toolsNo
malwareNo
regionsNo
sectorsNo
coverageNo
campaignsNo
operating_systemsNo

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 BundleA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
shapeNo"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_idYesThreat ID (e.g. TL-2026-0042)
pivot_limitNoInfrastructure pivots to embed, 1-200 (default 25). One threat can carry 150+; get_infrastructure_pivots returns the full set.
simulation_limitNoPlaybooks to embed, 1-20 (default 3).

Output Schema

ParametersJSON Schema
NameRequiredDescription
iocsNocanonical: FLAT array. (In v1 this is an object keyed by category under threat.iocs.)
ttpsNoCanonical MITRE technique ids, present in BOTH shapes.
_shapeNo
countsNocanonical: a denominator for every array key.
threatNo
regionsNo
sectorsNo
_envelopeNoShape manifest — announces that shape="canonical" exists.
canonicalNoPresent only under shape="both".
threat_idNo
simulationsNo
ttp_detailsNo
similar_threatsNov1: handler envelope {source_threat_id, count, similar[]} — an OBJECT, not an array.
infrastructure_pivotsNov1: handler envelope {threat_id, infrastructure_pivots[], coverage{}} — an OBJECT.

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines5/5

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 LevelA
Read-onlyIdempotent

Get the computed current threat-landscape level (a 0–25 rating of overall posture).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
maxNo
levelYes
scoreYes
criteriaNo
threats_observedNo

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 SimulationsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax playbooks to return (max 50). Omit for all — bodies are large.
platformNoReturn only this platform: windows, linux, python (also aws, macos, multi on a few rows). Omit for all.
threat_idYesThreat ID (e.g. TL-2026-0042)

Output Schema

ParametersJSON Schema
NameRequiredDescription
caveatNoWhy these do not prove your detections fire.
reasonNoPresent only on an empty result: no_simulations_for_threat | no_simulations_for_platform.
matchedNo
returnedNo
platformsNo
threat_idYes
truncatedNo
deprecatedNo
simulationsNo
total_simulationsNoAll archived playbooks for this threat, before platform/limit.
generation_stoppedNoDate generation stopped (2026-08-03).
available_platformsNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 TranscriptsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
threat_idYesThreat ID (e.g. TL-2026-0042)

Output Schema

ParametersJSON Schema
NameRequiredDescription
countNo
threat_idYes
transcriptsNo

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 IntelligenceA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesTool name (e.g. "Cobalt Strike", "Mimikatz")

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryNo
actorsNo
matchedYes
threatsNo
canonicalNo
membershipNo
prevalenceNo
entity_typeNo
top_techniquesNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CheckA
Read-onlyIdempotent

Lightweight liveness probe: confirms the API is reachable and your key is valid, and returns platform counts + the latest debrief date.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
statusYes'ok' | 'degraded'
tool_countNoTools the LIVE server exposes. If your client listed fewer, its catalog is stale.
catalog_hintNo
prompt_countNo
wire_versionNoNegotiated MCP protocol version.
api_reachableNo
catalog_sourceNoAlways 'live' here — this response came from the server, not a cached catalog.
platform_statsNo
server_versionNo
latest_debrief_dateNo
min_recommended_clientNo

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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)A
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoRow 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.
queryYesTLQL, e.g. `tool = "cobalt strike" AND sector = "healthcare" | stats count by nation`

Output Schema

ParametersJSON Schema
NameRequiredDescription
byNo
funcNo
modeYes'stats' when the query has a | stats pipe, otherwise rows.
rowsNo
countNoRows RETURNED, not rows matched.
limitNo
queryYes
groupsNo
columnsNo
has_moreNoTrue when rows (or, in stats mode, groups) were cut at the limit.
tier_gated_includedNoTrue when the caller's tier allows the c2_beacon/dns/infra observation types.

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 SchemaA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
grammarYes
row_countNo
rebuilt_atNo
duration_msNo
by_type_jsonNoJSON string of per-observation-type row counts.

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CampaignsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 50, max 200.
min_actorsNoOnly campaigns with at least this many DISTINCT actor labels (e.g. 2 for multi-actor campaigns).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
countNo
totalNo
caveatYesExplains text_supported and its false negatives. Do not drop it when summarising.
coverageNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 DebriefsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax debriefs to return (default 30, max 100)

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
totalNoTotal matching rows, when the handler reports one.
has_moreNoTrue when another page may exist.
next_cursorNoOpaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness3/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 SimulationsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax threats in this page (default 50, max 200)
offsetNoRow offset for paging (default 0). Use next_offset from the previous response.
include_facetsNoInclude the corpus filter vocabulary (filter_meta). Default false — it is ~20 KB and does not shrink with limit.

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalNoCorpus-wide threats that have simulations.
threatsNo
has_moreNo
returnedNoThreats in THIS page.
deprecatedNo
correlationNo
filter_metaNo
next_offsetNo
page_simulationsNoSimulation rows across the returned page only.
total_simulationsNoCorpus-wide simulation rows.
generation_stoppedNo

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 CategoriesA
Read-onlyIdempotent

List every threat category with its threat count across the whole corpus. Use to discover valid category filters for search_threats.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
total_categoriesNo

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 TransitionsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
basisNoFilter by evidence basis. Default 'any' (unfiltered, byte-identical to previous behaviour). Use 'attack_flow' for authored-causality rows only.
top_nNoMax transitions to return (default 5, max 20)
directionNo'forward' = techniques that typically follow (default); 'reverse' = techniques that typically precede
technique_idNoSource technique ID (e.g. T1059 or T1059.001)

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
totalNo
directionNo
transitionsNo
technique_idYes

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 NameA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesName or alias to resolve
typeNoOptional: actor|malware|tool|sector|region|technique|campaign

Output Schema

ParametersJSON Schema
NameRequiredDescription
uuidNo
queryYes
matchedYes
canonicalNoCanonical name — feed to get_actor / get_malware_intelligence / get_tool_intelligence.
entity_typeNo
matched_viaNo

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 ActorsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toolNoOnly actors with a threat using this tool (e.g. "Cobalt Strike")
sectorNoOnly actors with a threat targeting this sector (e.g. "Healthcare")
malwareNoOnly actors with a threat deploying this malware family (e.g. "LockBit")

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalNoTotal matching rows, when the handler reports one.
actorsNo
has_moreNoTrue when another page may exist.
next_cursorNoOpaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.
label_hygieneNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 SearchA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesA natural-language question or concept.

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryNo
chunksNo
resultsNo

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 DetectionsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoDetection type: spl, kql, or sigma
limitNoMax results (default 25, max 200)
queryYesSearch term (rule text, CVE, technique, etc.)
offsetNoRow offset for pagination (default 0)
severityNoFilter by severity: critical, high, medium, low

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 IOCsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoIOC category (e.g. network, file, behavioral)
limitNoMax results (default 25, max 100)
valueNoSubstring to match against IOC values

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
totalNoTotal matching rows, when the handler reports one.
has_moreNoTrue when another page may exist.
next_cursorNoOpaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 ThreatsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
osNoFilter to threats affecting an operating system (e.g. "Windows", "Linux", "VMware ESXi")
cveNoFilter by CVE id (e.g. CVE-2026-45321)
tagNoFilter by exact tag (e.g. "supply-chain-compromise")
toolNoFilter to threats using a tool (e.g. "Cobalt Strike", "Mimikatz")
limitNoMax results (default 20, max 100)
queryNoFree-text term across title/summary/description/CVE/actor (optional; AND-combined with filters)
cursorNoOpaque pagination cursor (next_cursor from a prior result); ignored when offset is given.
offsetNoRow offset for pagination (default 0).
sectorNoFilter by grounded industry sector (e.g. "Healthcare", "Government")
statusNoThreat status filter (e.g. active)
malwareNoFilter to threats deploying a malware family (e.g. "LockBit", "Vidar")
campaignNoFilter to threats in a named campaign/operation (e.g. "Snowflake campaign")
categoryNoe.g. SUPPLY_CHAIN, MALWARE, RANSOMWARE, VULNERABILITY, APT, PHISHING, ZERO_DAY (call list_threat_categories for the full vocabulary)
severityNocritical | high | medium | low
motivationNoFilter by motivation (e.g. financial, espionage)
nation_stateNoFilter by nation-state (e.g. Russia, China, Iran)
threat_actorNoFilter by attributed actor name/alias (e.g. "TeamPCP", "APT29")
created_afterNoISO date — only threats created on/after (e.g. 2026-05-01)
target_regionNoFilter by targeted region (e.g. APAC, Europe)
target_sectorNoFilter by targeted sector (e.g. Healthcare, Finance)
created_beforeNoISO date — only threats created on/before
mitre_techniqueNoFilter by MITRE technique id (e.g. T1059)
affected_productNoFilter by affected product/vendor (e.g. "npm", "Microsoft", "VS Code")

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
totalNoTotal matching rows, when the handler reports one.
has_moreNoTrue when another page may exist.
next_cursorNoOpaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 VulnerabilitiesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
cweNoWeakness id, e.g. CWE-79
kevNoOnly CISA KEV (known-exploited) CVEs
sortNotrending (default) | latest | priority | cvss | epss
limitNodefault 30, max 100
queryNoFree-text: a CVE id or keyword (matches id + description)
nucleiNoOnly CVEs with a nuclei detection template
vendorNoAffected vendor/product substring
windowNoOnly CVEs published within the last N days
has_pocNoOnly CVEs with a public proof-of-concept
epss_minNoMinimum EPSS exploitation probability, 0-1
severityNoCRITICAL | HIGH | MEDIUM | LOW

Output Schema

ParametersJSON Schema
NameRequiredDescription
sortNo
totalNo
facetsNo
paginationNo
vulnerabilitiesYes

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 IndicatorsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoSubstring match on the indicator value
asnNoAutonomous system, e.g. AS14061
tagNoCommunity tag substring, case-insensitive and normalized (e.g. phishing, asyncrat, c2)
typeNoIndicator type
limitNoMax rows (default 25, max 100)
offsetNoRow offset for paging
countryNoTwo-letter country code, e.g. RU
min_threatsNoOnly indicators linked to at least this many of our threats

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
totalNoTotal matching rows, when the handler reports one.
has_moreNoTrue when another page may exist.
next_cursorNoOpaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

  1. 47 tool updatesv8.2.1
    • Changedbulk_get_threats8 fields changed
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "\"summary\" (default, all 20 fit) | \"full\" (whole dossiers, max 3 ids per call)",
        +  "type": "string"
        +}
      • addedOutput schema / properties / count / description
        Added value: +"Rows actually present in threats[] — safe to iterate on."
      • addedOutput schema / properties / deferred_ids
        Added value: +{
        +  "items": {
        +    "description": "Ids NOT fetched because detail=\"full\" is batch-capped. Call again with these.",
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / deferred_reason
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / detail
        Added value: +{
        +  "description": "\"summary\" | \"full\" — which row shape threats[] carries.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / detail_hint
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / requested
        Added value: +{
        +  "description": "How many ids the caller supplied.",
        +  "type": "integer"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "threats",
        -  "missing"
        -]New value: +[
        +  "threats",
        +  "missing",
        +  "count"
        +]
    • Changedexport_attack_navigator5 fields changed
      • addedOutput schema / properties / description
        Added value: +{
        +  "description": "Includes the scoring unit (\"Score = …\").",
        +  "type": "string"
        +}
      • addedOutput schema / properties / metadata
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "name": {
        +        "type": "string"
        +      },
        +      "value": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / techniques / items / properties / color
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / techniques / items / properties / enabled
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / techniques / items / properties / score / description
        Added value: +"Threats using THIS technique (per-technique, not per-tactic). See description/metadata for the unit."
    • Changedget_actor8 fields changed
      • addedOutput schema / properties / actor_relationships
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "rel_type": {
        +        "type": "string"
        +      },
        +      "related_name": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / actor_relationships_coverage
        Added value: +{
        +  "description": "Present only when actor_relationships is empty: says the baseline has no row, not that the actor is unrelated.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / mitre / properties / techniques_returned
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / mitre / properties / techniques_total
        Added 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"
        +}
      • addedOutput schema / properties / mitre / properties / truncation_note
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / relationships / properties / shared_infra
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / relationships / properties / shared_techniques
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / relationships / properties / shared_tooling
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
    • Changedget_actor_intelligence5 fields changed
      • addedOutput schema / properties / actor_relationships
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "rel_type": {
        +        "type": "string"
        +      },
        +      "related_name": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / cross_actor_attribution / additionalProperties
        Added value: +true
      • removedOutput schema / properties / cross_actor_attribution / description
        Removed value: -"Shared entities across actors, or null when the attribution engine has nothing."
      • addedOutput schema / properties / cross_actor_attribution / properties
        Added 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"
        +  }
        +}
      • changedOutput schema / properties / cross_actor_attribution / type
        Previous value: -[
        -  "object",
        -  "null"
        -]New value: +"object"
    • Addedget_actor_relationships
    • Addedget_atlas_intelligence
    • Addedget_attack_flow
    • Changedget_c22 fields changed
      • changedInput schema / properties / limit / description
        Previous 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."
      • addedInput schema / properties / offset
        Added value: +{
        +  "description": "Skip this many records — 'correlations' only; the aggregate summary block stays whole across pages.",
        +  "type": "number"
        +}
    • Changedget_campaign_intelligence5 fields changed
      • addedOutput schema / properties / membership
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "grounded": {
        +      "type": "integer"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "title_match": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / prevalence / properties / actor_count / description
        Added value: +"TRUE distinct-actor prevalence, uncapped. The actors[] array is clipped to 20 — compare with actors_returned."
      • addedOutput schema / properties / prevalence / properties / actors_returned
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / prevalence / properties / threat_count_is_floor
        Added value: +{
        +  "description": "True when the membership fetch saturated, so threat_count under-counts.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / threats / items / properties / matched_via
        Added value: +{
        +  "description": "campaigns only: grounded | title | grounded+title",
        +  "type": "string"
        +}
    • Changedget_changelog10 fields changed
      • addedOutput schema / properties / count
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / entries
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "changes": {
        +        "items": {},
        +        "type": "array"
        +      },
        +      "date": {
        +        "type": "string"
        +      },
        +      "id": {},
        +      "title": {
        +        "type": "string"
        +      },
        +      "version": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / has_more
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / latest_entry_date
        Added value: +{
        +  "description": "Date of the newest entry — the feed cut-off.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • removedOutput schema / properties / result
        Removed value: -{
        -  "items": {
        -    "additionalProperties": true,
        -    "properties": {
        -      "changes": {
        -        "items": {},
        -        "type": "array"
        -      },
        -      "id": {}
        -    },
        -    "type": "object"
        -  },
        -  "type": "array"
        -}
      • addedOutput schema / properties / stale
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / stale_days
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / total
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / warning
        Added value: +{
        +  "description": "Present when the feed is stale; says what it does NOT cover.",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "result"
        -]New value: +[
        +  "entries"
        +]
    • Changedget_correlation_subgraph12 fields changed
      • addedInput schema / properties / edge_type
        Added 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"
        +}
      • changedInput schema / properties / min_fidelity / description
        Previous 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."
      • addedOutput schema / properties / counts
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "edges": {
        +      "type": "integer"
        +    },
        +    "nodes": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / edges / items / properties / co_occurrence_count
        Added value: +{
        +  "type": "integer"
        +}
      • removedOutput schema / properties / edges / items / properties / fidelity
        Removed value: -{
        -  "type": "number"
        -}
      • addedOutput schema / properties / edges / items / properties / fidelity_score
        Added value: +{
        +  "description": "Rounded 0-100.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / edges / items / properties / marginals
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "N": {
        +      "type": "integer"
        +    },
        +    "c": {
        +      "type": "integer"
        +    },
        +    "df_actor": {
        +      "type": "integer"
        +    },
        +    "df_tech": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / edges / items / properties / pmi
        Added value: +{
        +  "description": "NPMI edge types only (actor_technique, technique_cooccurrence).",
        +  "type": "number"
        +}
      • addedOutput schema / properties / edges / items / properties / weight_norm
        Added value: +{
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • removedOutput schema / properties / params
        Removed value: -{
        -  "additionalProperties": true,
        -  "properties": {},
        -  "type": "object"
        -}
      • addedOutput schema / properties / params_echo
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "type": "boolean"
        +}
    • Changedget_correlations2 fields changed
      • addedInput schema / properties / limit
        Added 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"
        +}
      • addedInput schema / properties / offset
        Added value: +{
        +  "description": "Paged engines only: skip this many rows.",
        +  "type": "number"
        +}
    • Changedget_cve8 fields changed
      • addedOutput schema / properties / affected_products_raw_count
        Added value: +{
        +  "description": "Entries before pre-release CPE collapsing.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / enrichment_note
        Added value: +{
        +  "description": "Present only on 'not_enriched'; names the seeding source.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / enrichment_status
        Added value: +{
        +  "description": "'enriched' or 'not_enriched'. On 'not_enriched' a blank CVSS/EPSS/age_days means NOT MEASURED, not measured-empty.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / threat_count
        Added value: +{
        +  "type": "integer"
        +}
      • changedOutput schema / properties / threat_ids / items / description
        Previous 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."
      • addedOutput schema / properties / threat_ids_derived_only
        Added 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"
        +}
      • addedOutput schema / properties / threat_ids_note
        Added value: +{
        +  "description": "Present only when the derived cve_details.threat_ids reverse index disagreed with the live join.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / threat_ids_source
        Added value: +{
        +  "description": "Always 'threats.cve_list (authoritative live join)' when the join ran.",
        +  "type": "string"
        +}
    • Changedget_cve_intelligence10 fields changed
      • addedOutput schema / properties / actors
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "actor": {
        +        "type": "string"
        +      },
        +      "threat_count": {
        +        "type": "integer"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / cve / properties / threat_ids
        Added value: +{
        +  "items": {
        +    "description": "Reconciled from threats.cve_list — the authoritative join. Pass to get_threat.",
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / cve / properties / threat_ids_note
        Added value: +{
        +  "description": "Present only when the derived cve_details reverse index disagreed.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / cve / properties / threat_ids_source
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / mitre
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "tactic": {
        +        "type": "string"
        +      },
        +      "technique": {
        +        "type": "string"
        +      },
        +      "technique_id": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / related_cves
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "cve_id": {
        +        "type": "string"
        +      },
        +      "is_kev": {
        +        "type": "boolean"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / threats
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "actor": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "id": {
        +        "type": "string"
        +      },
        +      "severity": {
        +        "type": "string"
        +      },
        +      "title": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / velocity_data / additionalProperties
        Added value: +true
      • addedOutput schema / properties / velocity_data / properties
        Added 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"
        +    ]
        +  }
        +}
      • changedOutput schema / properties / velocity_data / type
        Previous value: -[
        -  "object",
        -  "null"
        -]New value: +"object"
    • Changedget_cwe10 fields changed
      • addedOutput schema / properties / abstraction
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / common_consequences
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / detection_methods
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / likelihood_of_exploit
        Added value: +{
        +  "description": "MITRE's High/Medium/Low rating. CWE has NO CVSS severity — see severity_note.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / related_cve_count
        Added value: +{
        +  "description": "True total mapping to this CWE, which can exceed the 20 returned.",
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / related_cves
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / related_cves_note
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / related_cwes / items / description
        Added value: +"De-duplicated CWE ids — pass to get_cwe."
      • addedOutput schema / properties / related_cwes / items / type
        Added value: +"string"
      • addedOutput schema / properties / severity_note
        Added value: +{
        +  "type": "string"
        +}
    • Addedget_d3fend_posture
    • Changedget_daily_intel_bundle2 fields changed
      • addedOutput schema / properties / detail_hint
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / top_threats / description
        Added value: +"LEAN summary rows (the search_threats shape) — call get_threat(id) for a dossier."
    • Changedget_daily_theme9 fields changed
      • addedOutput schema / properties / tags_note
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / themes / items / properties / snapshot_threat_count
        Added value: +{
        +  "description": "How many threats existed when the theme sentence was written.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / themes / items / properties / tags / items / additionalProperties
        Added value: +true
      • addedOutput schema / properties / themes / items / properties / tags / items / properties
        Added value: +{
        +  "count": {
        +    "type": "integer"
        +  },
        +  "tag": {
        +    "type": "string"
        +  }
        +}
      • changedOutput schema / properties / themes / items / properties / tags / items / type
        Previous value: -"string"New value: +"object"
      • addedOutput schema / properties / themes / items / properties / tags_available
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / themes / items / properties / tags_source
        Added value: +{
        +  "description": "live | snapshot | none.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / themes / items / properties / theme_note
        Added value: +{
        +  "description": "Present when the sentence was written from fewer threats than the day ended with.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / themes / items / properties / threat_count / description
        Added value: +"Live count of that date's threats."
    • Changedget_enrichment_overview19 fields changed
      • addedOutput schema / properties / as_of
        Added value: +{
        +  "description": "Newest row timestamp - this is a nightly snapshot, not a live read.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / note
        Added value: +{
        +  "description": "States which advertised sources are lanes and which are fields of a lane.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / sources / items / properties / avg_enrichment_fields
        Added value: +{
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / sources / items / properties / coverage_basis
        Added value: +{
        +  "description": "'measured' | 'measured_zero' (really zero) | 'not_measured' (never computed) - the two used to be indistinguishable.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / sources / items / properties / coverage_pct
        Added value: +{
        +  "description": "Share of the corpus this lane reaches. Read WITH coverage_basis.",
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / sources / items / properties / hit_rate / description
        Added value: +"PER-LANE definition, not comparable across lanes. NULL = not measurable for this lane."
      • changedOutput schema / properties / sources / items / properties / hit_rate / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / properties / sources / items / properties / hit_rate_basis
        Added value: +{
        +  "description": "'measured' | 'not_measured'.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / sources / items / properties / last_event_time
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / sources / items / properties / provenance
        Added value: +{
        +  "description": "'native_d1' = computed from our own tables; 'harness_tl_osint_scan' = community-sourced, corroborating only.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / sources / items / properties / source / description
        Added value: +"Lane name (alias of source_name)."
      • addedOutput schema / properties / sources / items / properties / source_name
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / sources / items / properties / unique_entities
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / sources / items / properties / updated_at
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / stale_hours
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / summary / properties / avg_hit_rate / description
        Added value: +"Averaged ONLY over lanes reporting a real hit_rate."
      • changedOutput schema / properties / summary / properties / avg_hit_rate / type
        Previous value: -"number"New value: +[
        +  "string",
        +  "null"
        +]
      • addedOutput schema / properties / summary / properties / measured_zero_coverage
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / summary / properties / unmeasured_coverage
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Addedget_entity_aliases
    • Changedget_entity_profile7 fields changed
      • addedInput schema / properties / limit
        Added 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"
        +}
      • addedOutput schema / properties / rarity
        Added 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"
        +}
      • addedOutput schema / properties / top_neighbors / items / additionalProperties
        Added value: +true
      • addedOutput schema / properties / top_neighbors / items / properties
        Added 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"
        +  }
        +}
      • addedOutput schema / properties / top_neighbors / items / type
        Added value: +"object"
      • addedOutput schema / properties / top_neighbors_limit
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / top_neighbors_truncated
        Added value: +{
        +  "description": "True when more neighbours exist than were returned — raise `limit`.",
        +  "type": "boolean"
        +}
    • Addedget_flow_coverage
    • Addedget_flow_similar_threats
    • Changedget_infrastructure_pivots7 fields changed
      • addedOutput schema / properties / coverage
        Added 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"
        +}
      • addedOutput schema / properties / infrastructure_pivots / items / properties / category
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / infrastructure_pivots / items / properties / confidence
        Added value: +{
        +  "description": "Rarity-derived (Adamic-Adar) for shared_ioc rows; hand-set for curated_link rows.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / infrastructure_pivots / items / properties / ioc_type
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / infrastructure_pivots / items / properties / pivot_value
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / infrastructure_pivots / items / properties / source
        Added value: +{
        +  "description": "'shared_ioc' (derived from the same indicator universe the correlation graph scores) or 'curated_link'.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / infrastructure_pivots / items / properties / value_threat_count
        Added value: +{
        +  "description": "How many threats corpus-wide carry this value — 2 is a strong pivot, 40 is commodity.",
        +  "type": "number"
        +}
    • Changedget_ioc_blast_radius5 fields changed
      • addedOutput schema / properties / coverage
        Added 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"
        +}
      • addedOutput schema / properties / stats / properties / rings
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / stats / properties / sibling_iocs
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / stats / properties / total_actors
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / stats / properties / total_techniques
        Added value: +{
        +  "type": "integer"
        +}
    • Changedget_landscape_briefing11 fields changed
      • addedOutput schema / properties / briefings / items / properties / is_synthesis
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / fallback_note
        Added value: +{
        +  "description": "Names which date was served and which was skipped.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / latest / description
        Added value: +"The most recent REAL synthesis (see latest_is_fallback)."
      • addedOutput schema / properties / latest_age_hours
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / latest_generated_at
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / latest_is_fallback
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / latest_is_synthesis
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / narrative_ok
        Added value: +{
        +  "description": "Did the NEWEST run produce a real narrative?",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / newest_generated_at
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / page_size
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / stub_count
        Added value: +{
        +  "type": "integer"
        +}
    • Changedget_malware_intelligence5 fields changed
      • addedOutput schema / properties / membership
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "grounded": {
        +      "type": "integer"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "title_match": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / prevalence / properties / actor_count / description
        Added value: +"TRUE distinct-actor prevalence, uncapped. The actors[] array is clipped to 20 — compare with actors_returned."
      • addedOutput schema / properties / prevalence / properties / actors_returned
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / prevalence / properties / threat_count_is_floor
        Added value: +{
        +  "description": "True when the membership fetch saturated, so threat_count under-counts.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / threats / items / properties / matched_via
        Added value: +{
        +  "description": "campaigns only: grounded | title | grounded+title",
        +  "type": "string"
        +}
    • Changedget_mitre_gap_analysis19 fields changed
      • changedInput schema / properties / limit / description
        Previous 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."
      • changedInput schema / properties / tactic / description
        Previous 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."
      • addedOutput schema / properties / summary / properties / available_tactics
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / summary / properties / by_priority
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / summary / properties / by_tactic
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / summary / properties / corpus_total
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / summary / properties / has_more
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / summary / properties / returned
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / summary / properties / scoring
        Added value: +{
        +  "description": "States what debt_score counts.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / summary / properties / tactic_filter
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / summary / properties / total / description
        Added value: +"Techniques matching the tactic filter (the ranking denominator), not the page size."
      • addedOutput schema / properties / techniques / items / properties / debt_score / description
        Added value: +"Ranking unit. Higher = weaker coverage against more exposure; see summary.scoring."
      • addedOutput schema / properties / techniques / items / properties / detection_count
        Added value: +{
        +  "description": "Rules mapping this technique or its parent — NOT detections on threats that merely share it.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / techniques / items / properties / epss_max
        Added value: +{
        +  "type": "number"
        +}
      • addedOutput schema / properties / techniques / items / properties / is_covered / description
        Added value: +"True when at least one detection maps this technique (or its parent) in detections.mitre_mapping."
      • addedOutput schema / properties / techniques / items / properties / kev_exposure
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / techniques / items / properties / priority_label / description
        Added value: +"critical | high | medium | low, banded off debt_score."
      • addedOutput schema / properties / techniques / items / properties / technique_id / description
        Added value: +"Pass to get_mitre_technique."
      • addedOutput schema / properties / techniques / items / properties / threat_exposure
        Added value: +{
        +  "type": "integer"
        +}
    • Changedget_mitre_technique16 fields changed
      • addedInput schema / properties / include_threats
        Added 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"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "Max threats to return (default 50, max 500)",
        +  "type": "number"
        +}
      • addedInput schema / properties / offset
        Added value: +{
        +  "description": "Threat-list row offset for paging (default 0)",
        +  "type": "number"
        +}
      • addedOutput schema / properties / deprecated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / detail_hint
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / matrix
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / parent_technique
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / revoked
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / revoked_by
        Added value: +{
        +  "description": "Successor technique id when this one was retired — query that id instead.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / source
        Added value: +{
        +  "description": "'attack_catalog' (authoritative) | 'threat_mitre_fallback' | 'unknown'.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / tactics
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / threat_count
        Added value: +{
        +  "description": "TOTAL threats using this technique — compare against threats_returned to see whether the list is a page.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / threats_has_more
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / threats_offset
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / threats_omitted
        Added value: +{
        +  "description": "Present and true when include_threats=false suppressed the list.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / threats_returned
        Added value: +{
        +  "type": "integer"
        +}
    • Changedget_roadmap7 fields changed
      • addedOutput schema / properties / as_of
        Added value: +{
        +  "description": "Last date the roadmap table itself was edited.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / counts
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "completed": {
        +      "type": "integer"
        +    },
        +    "ideas": {
        +      "type": "integer"
        +    },
        +    "in_progress": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / generated_at
        Added value: +{
        +  "description": "When this response was produced.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / in_progress
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / stale
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / stale_days
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / warning
        Added value: +{
        +  "description": "Present when stale; says the statuses are unreconciled.",
        +  "type": "string"
        +}
    • Changedget_similar_threats2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max results (default 10, max 50)"New value: +"Max results (default 10, max 20 — the handler caps here)."
      • addedOutput schema / properties / counts
        Added 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"
        +}
    • Changedget_technique_rules9 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Default 50, max 200."New value: +"Default 50, max 100."
      • addedOutput schema / properties / rules / items / properties / technique_a / description
        Added value: +"Pass to get_mitre_technique."
      • addedOutput schema / properties / rules / items / properties / technique_a_name
        Added value: +{
        +  "description": "ATT&CK name for technique_a (null if the catalog does not know the id).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / rules / items / properties / technique_b / description
        Added value: +"Pass to get_mitre_technique."
      • addedOutput schema / properties / rules / items / properties / technique_b_name
        Added value: +{
        +  "description": "ATT&CK name for technique_b (null if the catalog does not know the id).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / summary / properties / has_more
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / summary / properties / returned
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / summary / properties / total / description
        Added value: +"Rules on THIS page (legacy field — use total_rules for the corpus count)."
      • addedOutput schema / properties / summary / properties / total_rules
        Added value: +{
        +  "type": "integer"
        +}
    • Changedget_threat8 fields changed
      • addedInput schema / properties / max_description
        Added value: +{
        +  "description": "Char budget for the narrative description. Default 1500; 0 drops it; -1 returns it whole.",
        +  "type": "number"
        +}
      • addedInput schema / properties / sections
        Added 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"
        +}
      • addedOutput schema / properties / _sections
        Added 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"
        +}
      • addedOutput schema / properties / description_chars
        Added value: +{
        +  "description": "True length of description when it was trimmed to max_description.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / description_truncated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / references / description
        Added value: +"Full bibliography. Present only under sections=references or sections=all."
      • addedOutput schema / properties / references_compact
        Added 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"
        +}
      • addedOutput schema / properties / references_summary
        Added 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"
        +}
    • Changedget_threat_bundle1 field changed
      • addedInput schema / properties / simulation_limit
        Added 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"
        +}
    • Changedget_threat_enrichment1 field changed
      • addedOutput schema / properties / coverage
        Added 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"
        +}
    • Changedget_threat_hunting_bundle16 fields changed
      • addedInput schema / properties / pivot_limit
        Added value: +{
        +  "description": "Infrastructure pivots to embed, 1-200 (default 25). One threat can carry 150+; get_infrastructure_pivots returns the full set.",
        +  "type": "integer"
        +}
      • addedInput schema / properties / shape
        Added 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"
        +}
      • addedInput schema / properties / simulation_limit
        Added value: +{
        +  "description": "Playbooks to embed, 1-20 (default 3).",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / _envelope
        Added value: +{
        +  "description": "Shape manifest — announces that shape=\"canonical\" exists.",
        +  "type": "object"
        +}
      • addedOutput schema / properties / _shape
        Added value: +{
        +  "type": "object"
        +}
      • addedOutput schema / properties / canonical
        Added value: +{
        +  "description": "Present only under shape=\"both\".",
        +  "type": "object"
        +}
      • addedOutput schema / properties / counts
        Added value: +{
        +  "description": "canonical: a denominator for every array key.",
        +  "type": "object"
        +}
      • addedOutput schema / properties / infrastructure_pivots / description
        Added value: +"v1: handler envelope {threat_id, infrastructure_pivots[], coverage{}} — an OBJECT."
      • addedOutput schema / properties / iocs
        Added 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"
        +}
      • addedOutput schema / properties / regions
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / sectors
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / similar_threats / description
        Added value: +"v1: handler envelope {source_threat_id, count, similar[]} — an OBJECT, not an array."
      • addedOutput schema / properties / threat_id
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / ttp_details
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "id": {
        +        "type": "string"
        +      },
        +      "name": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "tactic": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / ttps
        Added value: +{
        +  "description": "Canonical MITRE technique ids, present in BOTH shapes.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • removedOutput schema / required
        Removed value: -[
        -  "threat"
        -]
    • Changedget_threat_simulations11 fields changed
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "Max playbooks to return (max 50). Omit for all — bodies are large.",
        +  "type": "number"
        +}
      • addedInput schema / properties / platform
        Added value: +{
        +  "description": "Return only this platform: windows, linux, python (also aws, macos, multi on a few rows). Omit for all.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / available_platforms
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / caveat
        Added value: +{
        +  "description": "Why these do not prove your detections fire.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / deprecated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / generation_stopped
        Added value: +{
        +  "description": "Date generation stopped (2026-08-03).",
        +  "type": "string"
        +}
      • addedOutput schema / properties / matched
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / reason
        Added value: +{
        +  "description": "Present only on an empty result: no_simulations_for_threat | no_simulations_for_platform.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / returned
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / total_simulations
        Added value: +{
        +  "description": "All archived playbooks for this threat, before platform/limit.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "type": "boolean"
        +}
    • Changedget_threat_transcripts3 fields changed
      • addedOutput schema / properties / transcripts / items / additionalProperties
        Added value: +true
      • addedOutput schema / properties / transcripts / items / properties
        Added 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"
        +  }
        +}
      • addedOutput schema / properties / transcripts / items / type
        Added value: +"object"
    • Changedget_tool_intelligence5 fields changed
      • addedOutput schema / properties / membership
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "grounded": {
        +      "type": "integer"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "title_match": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / prevalence / properties / actor_count / description
        Added value: +"TRUE distinct-actor prevalence, uncapped. The actors[] array is clipped to 20 — compare with actors_returned."
      • addedOutput schema / properties / prevalence / properties / actors_returned
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / prevalence / properties / threat_count_is_floor
        Added value: +{
        +  "description": "True when the membership fetch saturated, so threat_count under-counts.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / threats / items / properties / matched_via
        Added value: +{
        +  "description": "campaigns only: grounded | title | grounded+title",
        +  "type": "string"
        +}
    • Changedhealth6 fields changed
      • addedOutput schema / properties / catalog_hint
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / catalog_source
        Added value: +{
        +  "description": "Always 'live' here — this response came from the server, not a cached catalog.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / min_recommended_client
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / prompt_count
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / tool_count
        Added value: +{
        +  "description": "Tools the LIVE server exposes. If your client listed fewer, its catalog is stale.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / wire_version
        Added value: +{
        +  "description": "Negotiated MCP protocol version.",
        +  "type": "string"
        +}
    • Changedhunt4 fields changed
      • changedInput schema / properties / limit / description
        Previous 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."
      • addedOutput schema / properties / count / description
        Added value: +"Rows RETURNED, not rows matched."
      • addedOutput schema / properties / has_more
        Added value: +{
        +  "description": "True when rows (or, in stats mode, groups) were cut at the limit.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / limit
        Added value: +{
        +  "type": "integer"
        +}
    • Changedhunt_schema7 fields changed
      • addedOutput schema / properties / grammar / properties / operators / items / additionalProperties
        Added value: +true
      • addedOutput schema / properties / grammar / properties / operators / items / properties
        Added value: +{
        +  "note": {
        +    "type": "string"
        +  },
        +  "op": {
        +    "type": "string"
        +  }
        +}
      • changedOutput schema / properties / grammar / properties / operators / items / type
        Previous value: -"string"New value: +"object"
      • addedOutput schema / properties / grammar / properties / quoting
        Added value: +{
        +  "description": "When a value must be quoted — read this before writing a CVE or relative-time filter.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / grammar / properties / stats / properties / functions / items / additionalProperties
        Added value: +true
      • addedOutput schema / properties / grammar / properties / stats / properties / functions / items / properties
        Added value: +{
        +  "aliases": {
        +    "items": {
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  "name": {
        +    "type": "string"
        +  },
        +  "note": {
        +    "type": "string"
        +  }
        +}
      • changedOutput schema / properties / grammar / properties / stats / properties / functions / items / type
        Previous value: -"string"New value: +"object"
    • Addedlist_campaigns
    • Changedlist_debriefs13 fields changed
      • addedOutput schema / properties / data / items / properties / daily_theme
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / data / items / properties / ioc_breakdown
        Added value: +{
        +  "description": "IOC counts keyed by type (network, file, infrastructure, …).",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / data / items / properties / ioc_total
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / data / items / properties / mitre_technique_count
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / data / items / properties / mitre_techniques_sample
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / data / items / properties / new_detections
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / data / items / properties / new_threats
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / data / items / properties / severity_counts
        Added value: +{
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • removedOutput schema / properties / data / items / properties / title
        Removed value: -{
        -  "type": "string"
        -}
      • addedOutput schema / properties / data / items / properties / top_actors
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / data / items / properties / top_categories
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / data / items / properties / total_threats
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / data / items / properties / updated_threats
        Added value: +{
        +  "type": "integer"
        +}
    • Changedlist_simulations13 fields changed
      • addedInput schema / properties / include_facets
        Added value: +{
        +  "description": "Include the corpus filter vocabulary (filter_meta). Default false — it is ~20 KB and does not shrink with limit.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Max results (default 50, max 200)"New value: +"Max threats in this page (default 50, max 200)"
      • addedInput schema / properties / offset
        Added value: +{
        +  "description": "Row offset for paging (default 0). Use next_offset from the previous response.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / correlation / properties / computed_over_threats
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / correlation / properties / scope
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / deprecated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / generation_stopped
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / has_more
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / next_offset
        Added value: +{
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / page_simulations
        Added value: +{
        +  "description": "Simulation rows across the returned page only.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / returned
        Added value: +{
        +  "description": "Threats in THIS page.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / total / description
        Added value: +"Corpus-wide threats that have simulations."
      • addedOutput schema / properties / total_simulations / description
        Added value: +"Corpus-wide simulation rows."
    • Changedpredict_mitre_transitions1 field changed
      • addedInput schema / properties / basis
        Added 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"
        +}
    • Changedsearch_actors4 fields changed
      • addedOutput schema / properties / actors / items / properties / also_grounded_as
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / actors / items / properties / merged_from
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / actors / items / properties / role
        Added 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"
        +}
      • addedOutput schema / properties / label_hygiene
        Added 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"
        +}
  2. 86 tool updatesv8.1.1
    • Changedbulk_get_cves2 fields changed
      • changedInput schema / properties / cve_ids / description
        Previous value: -"Array of CVE IDs (max 20)"New value: +"CVE IDs (max 20)"
      • changedOutput 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"
        +}
    • Addedbulk_get_threats
    • Removedenrich_iocs
    • Addedexplain_correlation
    • Addedexport_attack_navigator
    • Addedexport_detection
    • Addedexport_stix
    • Changedgenerate_c2_blocklist4 fields changed
      • removedInput schema / properties / format
        Removed value: -{
        -  "description": "Output format (default: cidr JSON)",
        -  "enum": [
        -    "cidr",
        -    "hosts",
        -    "plain"
        -  ],
        -  "type": "string"
        -}
      • removedInput schema / properties / framework
        Removed value: -{
        -  "description": "Filter by C2 framework (e.g. 'cobalt-strike', 'sliver', 'havoc')",
        -  "type": "string"
        -}
      • removedInput schema / properties / since_days
        Removed value: -{
        -  "description": "How many days back to include (default 30, max 365)",
        -  "type": "number"
        -}
      • changedOutput 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"
        +}
    • Addedget_actor
    • Changedget_actor_intelligence7 fields changed
      • changedInput schema / properties / name / description
        Previous value: -"Actor name or canonical alias"New value: +"Threat-actor name or alias (e.g. \"APT29\")"
      • addedOutput schema / properties / actor
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "name": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / cross_actor_attribution
        Added value: +{
        +  "description": "Shared entities across actors, or null when the attribution engine has nothing.",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / cves
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / mitre
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / threats
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / tools
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
    • Removedget_actor_profile
    • Addedget_attribution_coverage
    • Addedget_attribution_evidence
    • Addedget_c2
    • Removedget_c2_configs
    • Removedget_c2_cross_correlations
    • Addedget_c2_dns_intel
    • Removedget_c2_operators
    • Removedget_c2_stats
    • Removedget_c2_timeline
    • Removedget_c2_watermarks
    • Changedget_campaign_intelligence1 field changed
      • changedOutput 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"
        +}
    • Changedget_changelog2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max entries (default 20)"New value: +"Max entries (default 20, max 100)"
      • changedOutput 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"
        +}
    • Addedget_community_campaigns
    • Removedget_correlation_engine
    • Addedget_correlation_path
    • Addedget_correlation_subgraph
    • Addedget_correlations
    • Removedget_correlations_overview
    • Addedget_cve
    • Removedget_cve_details
    • Changedget_cve_intelligence4 fields changed
      • changedInput schema / properties / cve_id / description
        Previous value: -"CVE ID (e.g. CVE-2025-12345)"New value: +"CVE identifier (e.g. CVE-2024-3400)"
      • addedOutput schema / properties / cve
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "cve_id": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / related_detections
        Added value: +{
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / velocity_data
        Added value: +{
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
    • Addedget_cwe
    • Removedget_cwe_details
    • Addedget_daily_intel_bundle
    • Addedget_daily_theme
    • Addedget_debrief
    • Changedget_detection_detail13 fields changed
      • changedInput schema / properties / detection_id / description
        Previous value: -"Detection ID (e.g. 'det-001' or the detection name)"New value: +"Detection ID"
      • addedOutput schema / properties / detection_type
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / false_positives
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / id / type
        Added value: +"string"
      • addedOutput schema / properties / kql_query
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / mitre_mapping
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / name / type
        Added value: +"string"
      • addedOutput schema / properties / query
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / severity
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / sigma_rule
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / threat_id
        Added value: +{
        +  "description": "Pass to get_threat.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / threat_title
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / required
        Added value: +[
        +  "id"
        +]
    • Changedget_detections14 fields changed
      • addedInput schema / properties / cursor
        Added value: +{
        +  "description": "Opaque pagination cursor (next_cursor from a prior result). Decoded to an offset; ignored when offset is given.",
        +  "type": "string"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Max results (default 50, max 200)"New value: +"Max results (default 15, max 100)"
      • changedInput schema / properties / offset / description
        Previous value: -"Pagination offset (default 0)"New value: +"Row offset for pagination (default 0). Or pass cursor from a prior result."
      • removedInput schema / properties / search
        Removed value: -{
        -  "description": "Keyword search (matches detection name and description)",
        -  "type": "string"
        -}
      • removedInput schema / properties / severity
        Removed value: -{
        -  "description": "Severity level filter",
        -  "enum": [
        -    "critical",
        -    "high",
        -    "medium",
        -    "low"
        -  ],
        -  "type": "string"
        -}
      • changedInput schema / properties / type / description
        Previous value: -"Detection language filter"New value: +"Detection type: spl, kql, or sigma"
      • removedInput schema / properties / type / enum
        Removed value: -[
        -  "spl",
        -  "kql",
        -  "sigma",
        -  "all"
        -]
      • removedOutput schema / properties / count
        Removed value: -{
        -  "type": "number"
        -}
      • addedOutput schema / properties / data / items
        Added 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"
        +}
      • addedOutput schema / properties / has_more / description
        Added value: +"True when another page may exist."
      • addedOutput schema / properties / next_cursor
        Added value: +{
        +  "description": "Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • removedOutput schema / properties / next_offset
        Removed value: -{
        -  "type": [
        -    "number",
        -    "null"
        -  ]
        -}
      • addedOutput schema / properties / total
        Added value: +{
        +  "description": "Total matching rows, when the handler reports one.",
        +  "type": "integer"
        +}
      • addedOutput schema / required
        Added value: +[
        +  "data"
        +]
    • Addedget_engine_status
    • Changedget_enrichment_overview2 fields changed
      • addedOutput schema / properties / sources
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "hit_rate": {
        +        "type": "number"
        +      },
        +      "source": {
        +        "type": "string"
        +      },
        +      "total_events": {
        +        "type": "integer"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / summary
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "avg_hit_rate": {
        +      "type": "number"
        +    },
        +    "total_events": {
        +      "type": "integer"
        +    },
        +    "total_sources": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedget_entity_profile
    • Addedget_graph_campaigns
    • Addedget_infrastructure_pivots
    • Addedget_ioc_blast_radius
    • Changedget_ioc_dns4 fields changed
      • removedInput schema / properties / ioc_value
        Removed value: -{
        -  "description": "IOC value to look up (IP address, domain, or URL)",
        -  "type": "string"
        -}
      • addedInput schema / properties / value
        Added value: +{
        +  "description": "IP address or domain (stored DNS enrichment lookup)",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "ioc_value"
        -]New value: +[
        +  "value"
        +]
      • changedOutput 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"
        +}
    • Changedget_ioc_intelligence12 fields changed
      • removedInput schema / properties / ioc_value
        Removed value: -{
        -  "description": "IOC value (IP, domain, hash, URL)",
        -  "type": "string"
        -}
      • addedInput schema / properties / value
        Added value: +{
        +  "description": "Exact indicator value (IP, domain, hash, or URL)",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "ioc_value"
        -]New value: +[
        +  "value"
        +]
      • addedOutput schema / properties / consensus_score
        Added value: +{
        +  "description": "Multi-feed consensus; null when no feed has seen it.",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / dns_records
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / infrastructure_pivots
        Added 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"
        +}
      • addedOutput schema / properties / ioc_value
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / osint
        Added value: +{
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / threat_count
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / threats
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "id": {
        +        "description": "Pass to get_threat.",
        +        "type": "string"
        +      },
        +      "ioc_type": {
        +        "type": "string"
        +      },
        +      "title": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / required
        Added value: +[
        +  "ioc_value"
        +]
    • Addedget_landscape_briefing
    • Addedget_latest_debrief
    • Changedget_malware_intelligence2 fields changed
      • changedInput schema / properties / name / description
        Previous value: -"Malware family name (e.g. LockBit, Vidar)"New value: +"Malware family name (e.g. \"LockBit\", \"Vidar\")"
      • changedOutput 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"
        +}
    • Addedget_mitre_coverage
    • Changedget_mitre_gap_analysis4 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max results (default 20, max 100)"New value: +"Max techniques (default 20, max 100)"
      • changedInput schema / properties / tactic / description
        Previous value: -"Filter by MITRE tactic (e.g. 'initial-access', 'persistence', 'lateral-movement')"New value: +"Filter to one ATT&CK tactic (e.g. \"execution\")"
      • addedOutput schema / properties / summary
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "coverage_pct": {
        +      "type": "number"
        +    },
        +    "covered": {
        +      "type": "integer"
        +    },
        +    "gaps": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / techniques
        Added 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"
        +}
    • Addedget_mitre_technique
    • Addedget_osint
    • Addedget_osint_trends
    • Addedget_pivotal_entities
    • Changedget_platform_stats10 fields changed
      • addedOutput schema / properties / by_category
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / by_severity
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / top_actors
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "count": {
        +        "type": "integer"
        +      },
        +      "threat_actor": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / top_techniques
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "count": {
        +        "type": "integer"
        +      },
        +      "technique_id": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / total_actors
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / total_correlations
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / total_detections
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / total_iocs
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / total_threats
        Added value: +{
        +  "type": "integer"
        +}
      • addedOutput schema / properties / total_ttps
        Added value: +{
        +  "type": "integer"
        +}
    • Changedget_recent_threats10 fields changed
      • addedInput schema / properties / cursor
        Added value: +{
        +  "description": "Opaque pagination cursor (next_cursor from a prior result). Decoded to an offset; ignored when offset is given.",
        +  "type": "string"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Number of threats to return (default 10, max 50)"New value: +"Max results (default 15, max 100)"
      • addedInput schema / properties / offset
        Added value: +{
        +  "description": "Row offset for pagination (default 0). Or pass cursor from a prior result.",
        +  "type": "number"
        +}
      • removedOutput schema / properties / count
        Removed value: -{
        -  "type": "number"
        -}
      • addedOutput schema / properties / data
        Added 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"
        +}
      • addedOutput schema / properties / has_more
        Added value: +{
        +  "description": "True when another page may exist.",
        +  "type": "boolean"
        +}
      • removedOutput schema / properties / items
        Removed value: -{
        -  "type": "array"
        -}
      • addedOutput schema / properties / next_cursor
        Added value: +{
        +  "description": "Opaque cursor for the next page, or null when this is the last page or the endpoint ignores offset.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / total
        Added value: +{
        +  "description": "Total matching rows, when the handler reports one.",
        +  "type": "integer"
        +}
      • addedOutput schema / required
        Added value: +[
        +  "data"
        +]
    • Changedget_roadmap1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "completed": {
        +      "items": {},
        +      "type": "array"
        +    },
        +    "ideas": {
        +      "items": {},
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedget_similar_threats4 fields changed
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Source threat ID (e.g. TL-2026-0042)",
        +  "type": "string"
        +}
      • removedInput schema / properties / threat_id
        Removed value: -{
        -  "description": "Source threat ID (e.g. TL-2026-0042)",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "threat_id"
        -]New value: +[
        +  "id"
        +]
      • changedOutput 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"
        +}
    • Addedget_started
    • Addedget_technique_rules
    • Changedget_threat20 fields changed
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Threat ID (e.g. TL-2026-0042)",
        +  "type": "string"
        +}
      • removedInput schema / properties / threat_id
        Removed value: -{
        -  "description": "Threat ID (e.g., TL-2026-0042)",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "threat_id"
        -]New value: +[
        +  "id"
        +]
      • addedOutput schema / properties / attribution
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "confidence": {
        +      "type": "string"
        +    },
        +    "motivation": {
        +      "type": "string"
        +    },
        +    "nation_state": {
        +      "type": "string"
        +    },
        +    "threat_actor": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / category
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / created_at
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / description
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / detections
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "detection_type": {
        +        "type": "string"
        +      },
        +      "id": {
        +        "type": "string"
        +      },
        +      "name": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / id / description
        Added value: +"Threat ID (TL-YYYY-NNNN)."
      • addedOutput schema / properties / identifiers
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "aliases": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "cve": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "cwe": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / iocs
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / mitre_attack
        Added value: +{
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "tactic": {
        +        "type": "string"
        +      },
        +      "technique": {
        +        "type": "string"
        +      },
        +      "technique_id": {
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / osint
        Added value: +{
        +  "description": "Community-OSINT summary; null below Red tier or when unscanned.",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / references
        Added value: +{
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / severity
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "cvss": {
        +      "type": "number"
        +    },
        +    "level": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / status
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / summary
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / tags
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / updated_at
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / required
        Added value: +[
        +  "id"
        +]
    • Changedget_threat_bundle4 fields changed
      • changedInput schema / properties / include / description
        Previous 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"
      • removedInput schema / properties / include / enum
        Removed value: -[
        -  "full",
        -  "summary"
        -]
      • changedInput schema / properties / threat_id / description
        Previous value: -"Threat ID (e.g., TL-2026-0356)"New value: +"Threat ID (e.g. TL-2026-0042)"
      • changedOutput 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"
        +}
    • Addedget_threat_enrichment
    • Changedget_threat_hunting_bundle1 field changed
      • changedOutput 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"
        +}
    • Addedget_threat_level
    • Addedget_threat_simulations
    • Changedget_threat_transcripts2 fields changed
      • changedInput schema / properties / threat_id / description
        Previous value: -"Threat ID to get transcripts for"New value: +"Threat ID (e.g. TL-2026-0042)"
      • changedOutput 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"
        +}
    • Changedget_tool_intelligence2 fields changed
      • changedInput schema / properties / name / description
        Previous value: -"Tool name (e.g. Cobalt Strike, Mimikatz)"New value: +"Tool name (e.g. \"Cobalt Strike\", \"Mimikatz\")"
      • changedOutput 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"
        +}
    • Changedhealth7 fields changed
      • addedOutput schema / properties / api_reachable
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / latest_debrief_date
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / platform_stats
        Added value: +{
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / server_version
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / status / description
        Added value: +"'ok' | 'degraded'"
      • removedOutput schema / properties / version
        Removed value: -{
        -  "type": "string"
        -}
      • addedOutput schema / required
        Added value: +[
        +  "status"
        +]
    • Addedhunt
    • Addedhunt_schema
    • Addedlist_debriefs
    • Changedlist_simulations2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max threats to return (default 50)"New value: +"Max results (default 50, max 200)"
      • changedOutput 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"
        +}
    • Addedlist_threat_categories
    • Removedpredict_attack_path
    • Addedpredict_mitre_transitions
    • Changedresolve_entity1 field changed
      • changedOutput 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"
        +}
    • Changedsearch_actors8 fields changed
      • removedInput schema / properties / limit
        Removed value: -{
        -  "description": "Max results (default 20)",
        -  "type": "number"
        -}
      • changedInput schema / properties / malware / description
        Previous 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\")"
      • removedInput schema / properties / motivation
        Removed value: -{
        -  "description": "Filter by motivation (e.g. 'financial', 'espionage', 'destruction')",
        -  "type": "string"
        -}
      • removedInput schema / properties / nation_state
        Removed value: -{
        -  "description": "Filter by nation-state (e.g. 'Russia', 'China', 'Iran')",
        -  "type": "string"
        -}
      • removedInput schema / properties / query
        Removed value: -{
        -  "description": "Search term (actor name or alias)",
        -  "type": "string"
        -}
      • changedInput schema / properties / sector / description
        Previous 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\")"
      • changedInput schema / properties / tool / description
        Previous 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\")"
      • changedOutput 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"
        +}
    • Addedsearch_corpus_semantic
    • Changedsearch_detections12 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max results per page (default 25, max 200)."New value: +"Max results (default 25, max 200)"
      • changedInput schema / properties / offset / description
        Previous value: -"Pagination offset (0-based). Pass next_offset from the previous response to page through results."New value: +"Row offset for pagination (default 0)"
      • changedInput schema / properties / query / description
        Previous value: -"Search term (matches detection name and description)"New value: +"Search term (rule text, CVE, technique, etc.)"
      • changedInput schema / properties / severity / description
        Previous value: -"Severity level filter"New value: +"Filter by severity: critical, high, medium, low"
      • removedInput schema / properties / severity / enum
        Removed value: -[
        -  "critical",
        -  "high",
        -  "medium",
        -  "low"
        -]
      • changedInput schema / properties / type / description
        Previous value: -"Detection language filter"New value: +"Detection type: spl, kql, or sigma"
      • removedInput schema / properties / type / enum
        Removed value: -[
        -  "spl",
        -  "kql",
        -  "sigma",
        -  "all"
        -]
      • removedOutput schema / properties / count
        Removed value: -{
        -  "type": "number"
        -}
      • addedOutput schema / properties / data / items
        Added 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"
        +}
      • removedOutput schema / properties / has_more
        Removed value: -{
        -  "type": "boolean"
        -}
      • removedOutput schema / properties / next_offset
        Removed value: -{
        -  "type": [
        -    "number",
        -    "null"
        -  ]
        -}
      • addedOutput schema / required
        Added value: +[
        +  "data"
        +]
    • Changedsearch_iocs7 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max results (default 50)"New value: +"Max results (default 25, max 100)"
      • removedInput schema / properties / query
        Removed value: -{
        -  "description": "IOC value to search (IP, domain, hash, URL, or keyword)",
        -  "type": "string"
        -}
      • changedInput schema / properties / type / description
        Previous value: -"IOC type filter"New value: +"IOC category (e.g. network, file, behavioral)"
      • removedInput schema / properties / type / enum
        Removed value: -[
        -  "ip",
        -  "domain",
        -  "hash",
        -  "url",
        -  "network",
        -  "file",
        -  "behavioral",
        -  "all"
        -]
      • addedInput schema / properties / value
        Added value: +{
        +  "description": "Substring to match against IOC values",
        +  "type": "string"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "query"
        -]
      • changedOutput 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"
        +}
    • Addedsearch_threats
    • Addedsearch_vulnerabilities
    • Addedsearch_xscan_indicators
  3. 41 tool updatesv0.1.0
    • First observedbulk_get_cves
    • First observedenrich_iocs
    • First observedgenerate_c2_blocklist
    • First observedget_actor_intelligence
    • First observedget_actor_profile
    • First observedget_c2_configs
    • First observedget_c2_cross_correlations
    • First observedget_c2_operators
    • First observedget_c2_stats
    • First observedget_c2_timeline
    • First observedget_c2_watermarks
    • First observedget_campaign_intelligence
    • First observedget_changelog
    • First observedget_correlation_engine
    • First observedget_correlations_overview
    • First observedget_cve_details
    • First observedget_cve_intelligence
    • First observedget_cwe_details
    • First observedget_detection_detail
    • First observedget_detections
    • First observedget_enrichment_overview
    • First observedget_ioc_dns
    • First observedget_ioc_intelligence
    • First observedget_malware_intelligence
    • First observedget_mitre_gap_analysis
    • First observedget_platform_stats
    • First observedget_recent_threats
    • First observedget_roadmap
    • First observedget_similar_threats
    • First observedget_threat
    • First observedget_threat_bundle
    • First observedget_threat_hunting_bundle
    • First observedget_threat_transcripts
    • First observedget_tool_intelligence
    • First observedhealth
    • First observedlist_simulations
    • First observedpredict_attack_path
    • First observedresolve_entity
    • First observedsearch_actors
    • First observedsearch_detections
    • First observedsearch_iocs

TDQS

A3.6/5.0
Disambiguation2/5

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.

Naming Consistency4/5

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.

Tool Count1/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.

Completeness4/5

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

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    An 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.
    1
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    This 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
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A 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.
    237
    MIT

Latest Blog Posts

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