Skip to main content
Glama

Mallory

Server Details

Queries IOCs, vulnerabilities, threat actors and malware correlated from thousands of sources, retaining source-attributed evidence. Collection spans feeds, reports and advisories, social and dark-web monitoring, and Mallory's own sandboxing and internet scanning; a free community tier is available with an account and API key.

Ownership verified
Status
Healthy
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL

TDQS

A4/5.0

Scored across 36 tools

Disambiguation4/5

Most tools map cleanly to a single entity and action via list/get pairs, so an agent can usually tell them apart. However, searchVulnerabilities substantially duplicates listVulnerabilities, and queryApi can reproduce nearly any named list/get call, creating real misselection risk despite being documented as a fallback.

Naming Consistency5/5

All names are camelCase verb_noun, with consistent list<Entity>/get<Entity> pairs across the intel entities plus createFinding, updateFinding, bulkUpdateFindings, and linkFindingTicket. Minor verb deviations such as findAffectedProducts, searchVulnerabilities, and referenceObservables do not break the overall pattern.

Tool Count2/5

36 tools is well past the 25-tool threshold, driven by exposing separate list/get pairs for every intel entity plus a catch-all queryApi. The domain is broad, but the surface is heavy and includes a redundant searchVulnerabilities tool alongside listVulnerabilities.

Completeness4/5

Findings have create/read/update/bulk-update/ticket-link coverage with documented limits (no delete, no resolution_reason write), and intel entities are read-only with list/get plus queryApi reaching stories, detections, weaknesses, relationships, and search. Minor gaps are the lack of named tools for several queryApi-only domains and the inability to set resolution_reason.

Available Tools

36 tools
bulkUpdateFindingsAInspect

Change the status and/or severity of a SET of findings in the caller's own organization, selected either by filter or by an explicit list of uuids. Use it for "dismiss all the unrotated-secret findings", "mark everything on foo/bar medium". For ONE finding you already hold a uuid for, use updateFinding instead; this tool is for sets you can only describe.

READ THIS BEFORE CALLING — IT WRITES THE MOMENT IT IS CALLED. There is no dry run, no preview mode and no confirmation step inside this tool, and no single call that puts back what it changed. The check has to happen BEFORE the call, in conversation with the user:

  1. Work out the selection, and resolve it yourself with listFindings using the SAME filters.

  2. Show the user what it covers — the count, and the findings themselves (name them if there are only a few).

  3. Say in one sentence what will change and how many findings it affects.

  4. Get a plain yes. Then call this ONCE. Never call this tool to find out what would match: listFindings and queryApi answer that and write nothing. Never call it on your own initiative, and never as a tidy-up you decided on yourself.

SCOPE is required and has no default. Over MCP it must be "tenant" — every finding in the organization, including ones filed months ago by people who are not in this conversation. "this_thread" only means anything inside the Mallory chat app, which is the only place a conversation thread exists; here it can only fail with MISSING_THREAD. If you do get MISSING_THREAD, do not "fix" it by re-sending with "tenant": that is a far larger write than the one that just failed, and the user has not agreed to it.

SELECTING

  • Pass filters or uuids, never both, and never invent a uuid — use only uuids a previous tool result actually returned (at most 500).

  • A tenant selection needs at least one filter, or a uuid list — there is no "everything we have" call. A selection filtered ONLY by status and/or severity still covers essentially the whole organization; the result flags that as broad, and you must say so explicitly when you report back.

  • A phrase like "the unrotated-secret findings" names a problem TYPE, not an asset: find the definition first with queryApi, path "/v1/finding_definitions" (slug__contains / title__contains), then filter on definition_slug, or definition_slug__in when several definitions match the phrase. definition_category is a whole category and much broader than a slug — confirm before using it.

  • An asset is asset_identifier (e.g. "foo/bar" for a GitHub repo). Try the exact value first and fall back to asset_identifier__contains only if it matched nothing.

  • Add status: "open" unless the user said otherwise: re-dismissing already-dismissed findings is churn they did not ask for.

  • search is fuzzy full text over title, asset_identifier, body, summary, remediation and asset_details — the only way to reach a cloud account id, region or owner, none of which are filterable columns. It is also the easiest way to hit findings the user did not mean, so with search especially, show them the listFindings result before you call.

BOUNDS AND REFUSALS — each is an answer, not an obstacle to route around:

  • TOO_MANY_MATCHES: the selection is over the 500-finding limit for one update. Narrow it (a definition_slug, a category, an asset filter, a created_at range). Do NOT page through it, and do NOT split it into several calls to get under the limit — each call is its own write, and the user agreed to one change rather than to a sequence of them.

  • NO_MATCHES: nothing matched, or everything matched already holds the value you are setting. When you set ONE field on a filters selection, findings already at that value are excluded from the selection, so the count you get back is the real blast radius and repeating the call for the same request is inert. Setting status AND severity together drops that exclusion — the selector cannot express "not both at once" — so there the count can include findings that were already correct, and a repeat call writes them all again. A uuids selection is never narrowed that way — the uuid list IS the selection — so a repeat call there rewrites every finding you named. Never re-issue a call to find out whether the first one landed: the result told you. Tell the user there was nothing to change and stop. Do NOT loosen the filters and retry until something matches: a selection that only appeared after you widened it is not the one the user described.

  • PLAN_LIMIT / FORBIDDEN: nothing was written and nothing is broken. Say so plainly and do not retry.

In user-facing status messages, use "fixed" and "mark as fixed" consistently.

ENUM VALUES ARE CASE-SENSITIVE AND EACH FIELD HAS ITS OWN SET. severity is UPPERCASE (CRITICAL, HIGH, MEDIUM, LOW, INFO). status is lowercase with exactly three values: open, fixed, dismissed — "resolved", "closed" and "assigned" are not statuses. The resolution reasons (false_positive, accepted_risk, not_applicable, duplicate, fixed_externally, other) are a SEPARATE field that this tool cannot set: false_positive is not a status. definition_category is lowercase-hyphenated.

WHAT IT CANNOT DO: title, summary, body, remediation, confidence and qualifier — those are updateFinding, one finding at a time, because they are per-asset prose or part of core's dedupe key. resolution_reason is settable by NEITHER tool: it is recorded in the Mallory UI when someone closes a finding there, so listFindings can read and filter on it but nothing here writes it. It cannot create findings (createFinding). Setting status back to "open" is allowed but unusual; reopening two findings onto the same asset trips core's open-finding uniqueness constraint and rolls the whole batch back, so do not retry that — reopen one at a time.

NameRequiredDescriptionDefault
setYesThe change to apply to every selected finding. At least one field must be set.
scopeYesREQUIRED, and a real decision — there is no default and you must not guess. 'this_thread' restricts the update to findings created in THIS conversation; that is what a user means by 'those findings', 'the ones you just filed', 'these'. 'tenant' searches every finding in the organisation, including ones filed months ago by someone else — use it only when the user clearly means their whole findings backlog. If the wording could mean either, ASK before calling this tool.
uuidsNoExact findings to update, by uuid. Use ONLY when you already have real uuids from a previous tool result — never invent or guess one. Mutually exclusive with `filters`, and requires scope 'tenant': a uuid list is already exact, so thread scoping could only silently drop findings you named. Core still enforces that every uuid belongs to the caller's tenant.
filtersNoSelect findings by attribute instead of by uuid. Mutually exclusive with `uuids`. Required when scope is 'tenant'; optional when scope is 'this_thread' (omit it to mean every finding from this conversation).

TDQS

A4.9/5.0
Behavior5/5

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

No annotations exist, so the description carries the full burden and does: it discloses that it writes immediately with no dry run, no preview, no confirmation, and no single call that reverses the change. It further documents the 500-finding bound, what NO_MATCHES / TOO_MANY_MATCHES / PLAN_LIMIT / FORBIDDEN mean, the repeat-call semantics per selection type, and the batch-rollback on reopen collisions.

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?

Front-loaded with purpose then the write-now warning, and organized under clear headers (SCOPE, SELECTING, BOUNDS AND REFUSALS, ENUM VALUES, WHAT IT CANNOT DO). It is nonetheless very long, and the 'don't call it to see what matches' and 'don't retry after NO_MATCHES' points are restated in two or three places, which could be tightened.

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 destructive, nested-schema, no-annotations, no-output-schema batch mutation, everything an agent needs is present: pre-call verification procedure, scope decision rule, selection construction, error interpretation, and what the tool cannot do versus updateFinding/createFinding. It even flags that the result marks broad selections so the agent can report blast radius.

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?

Schema coverage is already 100%, but the description adds real selection strategy beyond it: filters/uuids are mutually exclusive, uuids must come from prior tool output, tenant selections need at least one filter, add status:"open" by default, try asset_identifier exact before __contains, and resolve problem-type phrases to definition_slug via queryApi first. Its enum case-sensitivity recap (severity UPPERCASE, status three lowercase values, resolution_reason being a separate unsettable field) resolves the most likely invocation error.

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 states a specific verb+resource+scope: change status/severity of a SET of findings in the caller's own organization, by filter or uuid list. It explicitly contrasts with the closest sibling ("For ONE finding you already hold a uuid for, use updateFinding instead"), so an agent can route between them without opening either 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?

Gives explicit when-to-use worked examples ("dismiss all the unrotated-secret findings"), when-not (never on own initiative, never as a self-decided tidy-up, never to preview), and names the alternative tools for each case: listFindings and queryApi answer 'what would match'. It even prescribes a four-step confirm-with-user workflow before calling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

createFindingAInspect

Create one or more findings in Mallory. A finding is a durable record that a specific problem exists on a specific asset belonging to the caller's own organization — not a chat message and not a note to yourself. It is visible in the Mallory UI to everyone in that organization, and nothing on this server deletes one: a finding filed by mistake can only be marked dismissed with updateFinding.

WRITES IMMEDIATELY. There is no draft, no preview and no confirmation step — calling this tool IS the write. Only call it when the user has asked, in so many words, for findings to be filed in Mallory ("create a finding for that", "file these"). Finishing an investigation is not permission to file its results: report them and let the user decide.

WHAT TO SEND

  • definition_slug must ALREADY EXIST in the catalog. Look one up with the queryApi tool, path "/v1/finding_definitions" (filter by category or severity to narrow). Never invent a slug, and never substitute a near-match for one that was rejected — that files the wrong kind of finding.

  • One finding per problem per asset. Five misconfigured buckets are five findings sharing a definition_slug with five different asset_identifier values, not one finding listing five buckets. Send the whole batch in ONE call (max 25): each is created independently, so one duplicate does not block the rest.

  • asset_type is a provider.service.object value (e.g. aws.s3.bucket, aws.iam.role, github.repo, azure.storage.account), or "generic" when nothing fits. Legacy underscore forms like "s3_bucket" are rejected.

  • summary / body / remediation are markdown, and are read by people who were not in your conversation: what is wrong, how you established it, and the actual fix.

  • evidence is one entry per thing you actually OBSERVED — the query and what it returned, the endpoint and its status, the file and the matching line. Three observations are three entries. Never write evidence for something you inferred rather than observed; lower confidence and say so in body instead.

ENUM VALUES ARE CASE-SENSITIVE AND EACH FIELD HAS ITS OWN SET. severity is UPPERCASE (CRITICAL, HIGH, MEDIUM, LOW, INFO) and optional — omit it and the definition's own default applies, which is usually right; override only when this instance is genuinely worse or milder than the type normally is, and say why in body. confidence is lowercase (low, medium, high). Status is not settable here: a finding is created open, and status values are lowercase (see updateFinding).

OUTCOMES come back per finding, in created and failed:

  • DUPLICATE — an open finding already covers that asset, and existing_finding_uuid names it. Say so and move on. Do NOT re-word the title and retry; to change the one that exists, call updateFinding with that uuid.

  • UNKNOWN_DEFINITION — the slug is not in the catalog. Look up a real one; do not guess a neighbouring slug.

  • INVALID — core rejected a field, most often asset_type. Fix that field, not the slug.

  • INVALID_ASSET_IDENTIFIER — asset_identifier names no asset (a placeholder such as "unknown", or a bare word such as a tool or data-source name, with asset_type "generic"). Nothing was written. Use the real affected asset from the source data (host:port, hostname, URL, account, repository); never invent one.

  • PLAN_LIMIT — findings are not included in this tenant's plan. The request was fine, nothing is broken and nothing was written: tell the user, pass on the upgrade link if the outcome carries one, and do not retry or reach for another tool to file it.

list_url is null outside the Mallory chat app — there is no conversation for an MCP call to scope a list to. Read a created finding back with getFinding using the uuid in created, or browse the tenant's findings with listFindings.

NameRequiredDescriptionDefault
findingsYesThe findings to create. Pass every finding from one investigation in a single call — each is created independently, so one duplicate does not block the rest.

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations present the description carries the full burden, and it does: it announces 'WRITES IMMEDIATELY', discloses there is no draft/preview/confirmation, states that nothing on the server deletes a finding (only dismissal via updateFinding), and spells out per-finding outcomes including DUPLICATE, UNKNOWN_DEFINITION, INVALID, INVALID_ASSET_IDENTIFIER and PLAN_LIMIT with the correct response to each.

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?

Well front-loaded: the 'WRITES IMMEDIATELY / only call when the user asked' warning precedes any field guidance, and the WHAT TO SEND / OUTCOMES sectioning makes a long text scannable. It is nonetheless verbose, with the batch-in-one-call and duplicate-avoidance points restated in both the body and the schema-adjacent prose.

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 no output schema, yet the description explains the return shape ('created' and 'failed' arrays with per-item outcomes), why `list_url` is null outside the chat app, and how to read a created finding back via getFinding. For a mutation tool with zero annotation coverage and a nested payload, nothing material is missing.

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?

Schema coverage is already 100%, so a 3 would be the floor — but the description adds genuinely new meaning: definition_slug must pre-exist and must not be replaced by a near-match, asset_type must be a provider.service.object value with legacy underscore forms rejected, severity should usually be omitted, and evidence is one entry per actual observation with inference excluded. That is semantics well beyond the field docs.

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 ('Create one or more findings in Mallory') and immediately defines the object ('a durable record that a specific problem exists on a specific asset belonging to the caller's own organization — not a chat message and not a note'). It also names the sibling tools that do the adjacent jobs (updateFinding, getFinding, listFindings, queryApi), so an agent can route 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?

Gives an explicit positive trigger ('create a finding for that', 'file these') and an explicit negative one ('Finishing an investigation is not permission to file its results'). It also routes the duplicate and correction cases to updateFinding rather than a retry, which is exactly the when-not guidance an agent needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

findAffectedProductsAInspect

Find technology products and software affected by a specific vulnerability. Provide either a CVE ID (e.g., CVE-2024-1234) or a vulnerability UUID. If you do not have a CVE ID, first use the vulnerability search tool. Returns a list of affected products with organization information and version details. Use this to understand the scope and impact of a vulnerability.

NameRequiredDescriptionDefault
vulnerability_idYesVulnerability identifier - either a CVE ID (e.g., 'CVE-2024-1234') or a UUID

TDQS

A3.8/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses the return shape ('list of affected products with organization information and version details') and the ID-resolution prerequisite, which is useful. However, it does not confirm this is a read-only operation, nor mention pagination, result caps, or behavior when the CVE has no known affected products.

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?

Front-loaded with purpose, followed by input, fallback, and return value in a compact order. The final sentence ('Use this to understand the scope and impact') is somewhat redundant with the opening, keeping it short of ideal economy.

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 single-parameter read lookup with no output schema, the description covers purpose, input forms, the fallback path, and what is returned. Missing only operational details like pagination or empty-result handling, which are minor for this tool's complexity.

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 parameter is already documented, and the description adds workflow semantics beyond the schema: how to obtain the identifier when missing. It doesn't clarify format distinctions (e.g., UUID source or case sensitivity), but the addition over the schema is real.

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?

Names a specific verb ('Find') and resource ('technology products and software affected by a specific vulnerability'), so an agent can tell this apart from getProduct/listProducts/getVulnerability. It doesn't explicitly contrast with getVulnerability, which likely also surfaces affected products, so the sibling differentiation is implicit rather than stated.

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?

Gives a clear entry condition ('Provide either a CVE ID or a vulnerability UUID') and an explicit prerequisite workflow ('If you do not have a CVE ID, first use the vulnerability search tool'). It never states when NOT to use it or what to do if the ID is unknown, but the positive guidance is concrete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAdvisoryAInspect

Fetch a single Mallory advisory by identifier (an advisory UUID) and return its full detail. Returns: advisory title/identifier, source/vendor, severity, affected products and vulnerabilities, and published date. If you only have a name or search terms, call listAdvisories first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe advisory identifier — an advisory UUID.

TDQS

A4.5/5.0
Behavior3/5

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

With no annotations, the description carries the full disclosure burden. It does useful work by enumerating the return payload (title/identifier, vendor, severity, affected products, vulnerabilities, published date) and framing the tool as a pure fetch. However, it says nothing about behavior when the UUID is not found, whether results are cached or permission-gated, or any rate limits.

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 tight sentences: purpose and return shape first, then fallback resolution, then the alternative tool for adjacent use cases. No filler and correctly 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?

There is no output schema, so the description must convey return values, and it does so field by field. For a single-parameter read tool, nothing an agent needs in order 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.

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, but the description adds meaning by reinforcing that the identifier must be an advisory UUID specifically and by explaining how to obtain one via listAdvisories. That is real semantic value beyond the schema text.

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 – 'Fetch a single Mallory advisory by identifier (an advisory UUID)' – and states that it returns full detail. It is distinguishable at a glance from listAdvisories and queryApi, which are both named.

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 an explicit routing rule for the main ambiguity: if you only have a name or search terms, call listAdvisories first to resolve the identifier. It also excludes relationship pivots and cross-entity queries, directing those to queryApi.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAttackPatternAInspect

Fetch a single Mallory attack pattern by identifier (a MITRE ATT&CK ID (e.g. T1566), a UUID, or the technique name) and return its full detail. Returns: mitre_id, name, description, tactic(s), and associated threat actors and malware. If you only have a name or search terms, call listAttackPatterns first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe attack pattern identifier — a MITRE ATT&CK ID (e.g. T1566), a UUID, or the technique name.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the burden itself, and it does disclose the return payload (mitre_id, name, description, tactic(s), threat actors, malware) and implies a read-only single-record fetch. It stops short of stating not-found/error behavior or authentication requirements, which is the remaining gap for a zero-annotation tool.

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 tight sentences: what it fetches and returns, then the disambiguation rule, then the escape hatch to the general query tool. Front-loaded with the primary action and no filler.

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 no output schema, so listing the returned fields is genuinely necessary and present, and the identifier formats are covered. The only shortfall is unstated behavior when the identifier matches nothing or is ambiguous, which matters for a lookup by free-form name.

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 defines identifier as a MITRE ATT&CK ID, UUID, or technique name with the T1566 example. The description restates exactly that, adding no format precedence or fallback behavior beyond the schema. 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?

Starts with a specific verb and resource ("Fetch a single Mallory attack pattern by identifier") and enumerates the accepted identifier forms plus the returned fields. It is clearly distinguishable from listAttackPatterns (enumeration) and queryApi (pivots/advanced queries) by name.

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 routes the agent: if you only have a name or search terms, call listAttackPatterns first; for relationship pivots or cross-entity queries, use queryApi. Both the when-to-use and the when-not-to-use conditions are stated with the named alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getBreachAInspect

Fetch a single Mallory breach by identifier (a UUID or the breach internal_name) and return its full detail. Returns: name, description, affected organizations, record_type and loss_type, affected record counts, associated threat actors/malware/attack-patterns, and dates. If you only have a name or search terms, call listBreaches first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe breach identifier — a UUID or the breach internal_name.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden and largely does so: it enumerates the returned fields (organizations, record counts, linked threat actors/malware/attack patterns, dates), which is essential since there is no output schema. It omits error behavior for a malformed or non-matching identifier, authentication needs, and pagination/size limits.

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, front-loaded with the action, then the return payload, then the two escalation paths. Nothing is redundant given the absence of an output schema, where the return-field list is genuinely load-bearing.

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 single-parameter read tool with no annotations and no output schema, the description covers action, identifier source, return contents, and alternatives — enough to call it correctly. Only failure modes and result-size expectations are left unstated.

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 schema already documents that identifier is "a UUID or the breach internal_name"; the description restates the same fact without adding format examples or validity rules. Baseline 3 applies because the schema does 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?

Names a specific verb and resource ("Fetch a single Mallory breach by identifier") and immediately constrains the domain to Mallory breaches with full detail. It is clearly distinguishable from listBreaches (listing) and queryApi (cross-entity), so an agent can route 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?

Explicitly states the fallback path: "If you only have a name or search terms, call listBreaches first to find the exact identifier," and names queryApi for relationship pivots. Both the alternative and the condition selecting it are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getExploitAInspect

Fetch a single Mallory exploit by identifier (a UUID or a CVE ID) and return its full detail. Returns: title/name, description, source and maturity, and the vulnerabilities (CVEs) it targets. If you only have a name or search terms, call listExploits first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe exploit identifier — a UUID or a CVE ID.

TDQS

A4.5/5.0
Behavior4/5

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

No annotations are provided, so the description carries the disclosure burden, and it does more than most: it enumerates the payload fields (title/name, description, source and maturity, targeted CVEs) in the absence of an output schema. It does not mention permissions, rate limits, or behavior on a non-existent identifier, which keeps it from a 5.

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 with a distinct job: what it does, what it returns, and where to go instead. The core action and return contents are front-loaded before the routing guidance.

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 read tool with no output schema, the description covers action, accepted identifiers, return fields, and sibling alternatives. An agent has everything needed to select and invoke it correctly without further context.

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 is documented in the schema as 'a UUID or a CVE ID'. The description restates the same accepted identifier forms without adding syntax, format constraints, or fallback behavior, so the schema is doing the semantic work.

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 ('Fetch a single Mallory exploit by identifier') and immediately enumerates what is returned, so the agent knows exactly what it gets. It explicitly distinguishes itself from sibling listExploits (lookup vs. discovery) and queryApi (single-entity vs. pivots).

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?

Names both the precondition and the alternative: 'If you only have a name or search terms, call listExploits first to find the exact identifier', and routes relationship/cross-entity work to queryApi. The when-to-use and when-not-to-use conditions are both explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getFindingAInspect

Fetch a single Mallory finding by identifier (a UUID (nothing else resolves)) and return its full detail. Returns: title, status, severity, confidence, the owning definition's slug/title/category, asset type and identifier, resolution_reason, the thread_uuid of the investigation that produced it, and timestamps; the detail object adds body / summary / remediation / evidence, any linked external tickets, and entities — the threat actors, vulnerabilities and stories this finding resolved to, which is the pivot back into Mallory's intel graph. If you only have a name or search terms, call listFindings first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe finding identifier — a UUID (nothing else resolves).

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden and does so well: it lists returned fields, explains what the detail object adds, and identifies `entities` as the pivot into the intel graph. It does not explicitly discuss read-only semantics, auth requirements, or not-found behavior, keeping it short of a 5.

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 purpose and return shape, then alternatives. The longer return-field list earns its place because no output schema exists.

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 fetch tool with no output schema, the description provides enough detail about returned fields, linked tickets, and entities to call it correctly and understand the payload. Alternatives are also covered.

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 identifier parameter is already well documented in the schema. The description reinforces that only a UUID resolves, but adds no syntax or format detail beyond the structured field; 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?

States a specific verb and resource: fetch a single Mallory finding by identifier and return full detail. It clearly distinguishes itself from listFindings and queryApi by naming both siblings and their roles.

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 says to call listFindings first when only a name or search terms are available, and to use queryApi for relationship pivots and advanced cross-entity queries. It also states the identifier must be a UUID, which prevents wasted calls.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getMalwareAInspect

Fetch a single Mallory malware by identifier (a UUID or the malware family name (e.g. Cobalt Strike)) and return its full detail. Returns: name/display_name plus aliases, description, capabilities, family, associated threat actors and ATT&CK techniques, related vulnerabilities, and trending activity. If you only have a name or search terms, call listMalware first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe malware identifier — a UUID or the malware family name (e.g. Cobalt Strike).

TDQS

A4.3/5.0
Behavior4/5

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

No annotations exist, so the description carries the burden; it discloses the return payload in detail (aliases, capabilities, family, threat actors, ATT&CK techniques, related vulnerabilities, trending activity) and the prerequisite of resolving an exact identifier. It does not mention auth requirements, error behavior for unknown identifiers, or whether results are cached/rate limited, which keeps it below a 5.

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?

Front-loaded with the action and identifier, followed by return contents, then escalation guidance — a sensible ordering. The return-field enumeration is somewhat long but each item is informative rather than filler.

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 no output schema, the description compensates by enumerating return fields, and it covers the identifier prerequisite and alternatives. Minor gaps remain around failure modes (unknown identifier) and read-only/safety characterization, which annotations would otherwise supply.

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 already documents both accepted forms (UUID or family name such as 'Cobalt Strike'). The description restates the same constraint without adding format examples, case-sensitivity, or ambiguity handling, 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?

States a specific verb ('Fetch'), resource ('a single Mallory malware'), and scope ('by identifier') plus the detail level returned. It is clearly distinguishable from listMalware (search) and queryApi (pivots), both named explicitly.

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 routing: 'If you only have a name or search terms, call listMalware first to find the exact identifier' and 'For relationship pivots ... and advanced cross-entity queries, use queryApi.' Both the when and the when-not with named alternatives are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getObservableAInspect

Fetch a single Mallory observable (IOC) — an IP, domain, URL, email address, or file hash — with its reputation/opinion data. Identify it EITHER by uuid, OR by the (type, name) pair: e.g. type='domain' name='evil.example.com'; type='ip.v4' name='1.2.3.4'; type='hash.sha256' name=''. Returns the observable's type, value, verdict/opinion summary, and linked references. To filter/search observables use listObservables; to get the IOCs Mallory extracted from a specific report use referenceObservables.

NameRequiredDescriptionDefault
nameNoObservable value, e.g. '1.2.3.4', 'evil.example.com', a file hash. Provide together with type.
typeNoObservable type, e.g. ip.v4, ip.v6, domain, url, email, hash.md5, hash.sha1, hash.sha256. Provide together with name.
uuidNoThe observable UUID. Provide this OR (type + name).

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations present, the description carries the full disclosure burden, and it does most of the work: it states what can be passed, that either of two identifier shapes is accepted, and what comes back (type, value, verdict/opinion summary, linked references). It does not cover failure behavior when an IOC is not found or whether both identifiers may be supplied simultaneously, which is the remaining gap for an annotation-free read tool.

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?

Four sentences, front-loaded with the purpose and identifier rules, then return shape, then sibling routing. Every sentence carries actionable information; nothing is filler or redundant repetition of the name.

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 no output schema and no annotations, so the description has to describe returns itself — which it does at a field level (type, value, verdict/opinion summary, references). Given only 3 optional params this is nearly complete; only not-found/error behavior and whether identifiers are mutually exclusive are left unspecified.

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 the uuid-vs-(type+name) relationship and lists the type values, so the description's examples largely restate structured data. The worked pairings (type='domain' name='evil.example.com') add only marginal clarity over the enum-like list already in 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?

Opens with a specific verb and resource ("Fetch a single Mallory observable (IOC)") and immediately enumerates the concrete value types it covers (IP, domain, URL, email, file hash), so the resource is unambiguous. It also names the two nearest siblings (listObservables, referenceObservables) and what they do instead, which lets an agent distinguish it 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?

Explicitly states the selection rule against alternatives: use listObservables to filter/search, referenceObservables to get IOCs extracted from a specific report. It also states the two acceptable identification paths (uuid OR type+name), removing any ambiguity about preconditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getOrganizationAInspect

Fetch a single Mallory organization by identifier (a UUID or the organization name) and return its full detail. Returns: name, description, associated products and breaches, and mention activity. If you only have a name or search terms, call listOrganizations first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe organization identifier — a UUID or the organization name.

TDQS

A4.7/5.0
Behavior4/5

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

With no annotations, the description carries the burden: it makes the read-only nature clear, enumerates what the response contains (name, description, products, breaches, mention activity), and warns that ambiguous/search-term identifiers require a prior lookup. It stops short of describing failure behavior when the identifier doesn't resolve or any ambiguity/rate-limit handling.

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 tight sentences: what it does and returns first, then the fallback lookup, then the alternative tool. Zero filler and correctly 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 single-parameter read tool with no output schema, the description covers purpose, return payload, and both routing alternatives, leaving nothing an agent needs in order to call 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?

Schema coverage is already 100%, so the baseline is 3; the description adds value by clarifying that the identifier must be an exact UUID or exact organization name and that partial names/search terms will not work. That meaningfully constrains how the parameter should be populated.

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 ('Fetch a single Mallory organization') and immediately bounds the scope to a single record by identifier. It explicitly contrasts itself with listOrganizations (lookup) and queryApi (relationship pivots), so an agent can distinguish it from siblings without opening a 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?

Gives an explicit routing rule: if you only have a name or search terms, call listOrganizations first to resolve the exact identifier. It also names queryApi as the alternative for relationship pivots and cross-entity queries, with the condition that selects it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getProductAInspect

Fetch a single Mallory product by identifier (a product UUID) and return its full detail. Returns: vendor and product name, CPE, description, and links to advisories and vulnerabilities. If you only have a name or search terms, call listProducts first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe product identifier — a product UUID.

TDQS

A4.7/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and largely meets it: it enumerates the returned content (vendor, product name, CPE, description, advisory/vulnerability links) and the read-only intent is unambiguous from "Fetch." It does not state what happens when the UUID doesn't resolve (error vs. empty), which is the main remaining behavioral gap for a no-annotation tool.

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 serving a distinct purpose: what it does, what it returns, and which siblings to use instead. The core action is front-loaded 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?

For a single-parameter lookup with no output schema, the description covers purpose, return shape, identifier sourcing, and alternative routing. Nothing an agent needs in order to call this correctly 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, but the description adds real value beyond the schema by specifying that the identifier is a product UUID and by explaining how to obtain one via listProducts. It stops short of format/validation details, but the schema's minLength and additionalProperties already cover 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 states a precise verb+resource combination ("Fetch a single Mallory product by identifier") and explicitly scopes the result to full detail for one entity. It is clearly distinguishable from listProducts and the other get* siblings by naming the identifier type (product UUID) up front.

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 two explicit alternatives with their selecting conditions: call listProducts when you only have a name or search terms, and use queryApi for relationship pivots or cross-entity queries. An agent never has to guess which sibling to pick.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getReferenceAInspect

Look up a Mallory reference — a source document (article, report, advisory, blog post, or social post) that Mallory ingested and analyzed. Two modes: (1) pass reference with a UUID, url_hash, or a pasted Mallory reference URL to fetch that exact reference; (2) pass urlFilter with a substring of the source's web URL (or its slug) to resolve which reference Mallory has for an article when you only have its web address. Returns reference metadata (source, title/topic, published date, URL). To then pull the IOCs/observables Mallory extracted from a reference, call referenceObservables with the reference's UUID.

NameRequiredDescriptionDefault
limitNoMax references to return in urlFilter (search) mode. Ignored when looking up a single reference.
referenceNoA reference UUID, url_hash, or a pasted Mallory reference URL (e.g. 'https://app.mallory.ai/references/{uuid}'). Provide this OR urlFilter.
urlFilterNoA case-insensitive substring of the source's web URL (or article slug) to resolve the matching reference(s) when you don't have a UUID. Provide this OR reference.

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden and does well: it states the return contents (source, title/topic, published date, URL) and the dual-mode behavior. It stops short of stating empty/no-match behavior or confirming read-only semantics, which are minor but real gaps for a lookup tool.

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?

Front-loaded with the resource definition, then cleanly numbered modes, then return values and a next-step pointer. Slightly longer than strictly necessary since some parameter detail duplicates the schema, but well organized with no filler.

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 3-param, no-annotation, no-output-schema lookup, the description is nearly complete: it defines the resource, both modes, and the return shape. It omits empty-result behavior and pagination guidance for urlFilter mode, keeping it from a 5.

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 all three parameters, including the 'provide this OR' relationship and limit semantics. The description's parameter prose largely restates the schema, adding only the mode framing, so a 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?

States a specific verb (look up) and resource (Mallory reference), and defines that resource precisely as a source document Mallory ingested and analyzed, with concrete examples (article, report, advisory). It is clearly distinguishable from siblings and names referenceObservables as the adjacent tool.

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 enumerates two modes and the condition that selects each: pass `reference` when you have a UUID/url_hash/pasted URL, or `urlFilter` when you only have a web address. It also routes to referenceObservables for the logical next step, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getSoftwareExtensionAInspect

Fetch a single Mallory software extension by identifier (an extension UUID) and return its full detail. Returns: extension name, marketplace/ecosystem, publisher, install count, description, and known configurations. If you only have a name or search terms, call listSoftwareExtensions first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe software extension identifier — an extension UUID.

TDQS

A4.7/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden, and it does disclose the operation is a read that returns full detail plus the specific fields returned (name, marketplace, publisher, install count, description, configurations). It does not cover error behavior for an unknown identifier, which keeps it short of a 5.

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 short sentences, each doing distinct work: what it fetches, what comes back, and how to resolve the input. Front-loaded with the action and resource, with zero 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?

There is no output schema, so the description compensates by enumerating the returned fields, and the single required parameter is fully explained including its acquisition path. An agent has everything needed to call it correctly on the first attempt.

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 UUID format is already documented, but the description adds practical meaning by explaining how to obtain the identifier via listSoftwareExtensions. That is genuine value beyond the schema rather than a restatement.

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 (fetch) and resource (Mallory software extension) with the exact lookup key (extension UUID) and the detail returned. It is unambiguously distinct from listSoftwareExtensions (enumeration) and queryApi (cross-entity pivots), which are named explicitly.

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 an explicit prerequisite path: if you only have a name or search terms, call listSoftwareExtensions first to resolve the identifier. It also names the alternative for relationship pivots and advanced queries (queryApi), so the agent knows both when to use this tool and when not to.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getSoftwarePackageAInspect

Fetch a single Mallory software package by identifier (a package UUID) and return its full detail. Returns: package name, ecosystem, description, known configurations, and supply-chain compromise evidence. If you only have a name or search terms, call listSoftwarePackages first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe software package identifier — a package UUID.

TDQS

A4.7/5.0
Behavior4/5

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

No annotations, so the description carries the burden, and it discloses the return payload (name, ecosystem, description, configurations, compromise evidence), which tells the agent what a successful call yields. It omits error behavior, permissions, and what happens for a nonexistent UUID, so it stops short of fully transparent.

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, front-loaded with the core action, then the return contents, then the disambiguation rules. No filler and no 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?

With no output schema, the description compensates by enumerating the returned fields, and with a single fully documented parameter the definition covers everything needed to call 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?

Schema coverage is 100% and the schema already states 'package UUID', so baseline is 3; the description adds value by telling the agent what to do when it lacks an identifier (call listSoftwarePackages), clarifying the expected value's origin.

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?

Starts with a specific verb and resource ('Fetch a single Mallory software package by identifier') and scopes it as full-detail retrieval, which distinguishes it from the list/get 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 routes the agent: use listSoftwarePackages first when only a name or search terms are available, and queryApi for relationship pivots or cross-entity queries. Both alternatives and their selecting conditions are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getThreatActorAInspect

Fetch a single Mallory threat actor by identifier (a UUID or the actor's name (e.g. APT29, Lazarus Group)) and return its full detail. Returns: canonical name/display_name plus aliases, description, motivation, sponsor, family, targeted industries and source/target geographies, and trending activity. If you only have a name or search terms, call listThreatActors first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe threat actor identifier — a UUID or the actor's name (e.g. APT29, Lazarus Group).

TDQS

A4.5/5.0
Behavior4/5

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

No annotations are provided, so the description carries the disclosure burden; 'Fetch' plus the enumerated result fields (aliases, motivation, sponsor, targeted industries, trending activity) make clear this is a non-mutating detail read with a rich payload. It omits what happens on a not-found or ambiguous identifier, which is the one behavioral gap for an unannotated tool.

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 with a distinct job: what it fetches, what comes back, and where to route instead. The core verb and scope are front-loaded with 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 one-parameter read tool with no output schema, the description supplies both the input contract and an explicit field-level picture of the return value, plus sibling routing. Nothing an agent needs in order 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% and the single parameter already documents the UUID-or-name dual form with the same examples, so the description adds little new semantic detail. It reinforces the identifier resolution workflow, but that is usage guidance rather than parameter 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?

States a specific verb and resource ('Fetch a single Mallory threat actor by identifier') and scopes the return payload ('full detail'). It clearly separates itself from listThreatActors (search/list) and queryApi (relationship pivots), so an agent can choose it without opening the 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 prescribes the alternative when the exact identifier is unknown ('call listThreatActors first to find the exact identifier') and names queryApi for relationship pivots and cross-entity queries. Both when-to-use and when-to-use-something-else are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getVulnerabilityAInspect

Fetch a single Mallory vulnerability by identifier (a CVE ID (e.g. CVE-2024-1234) or a UUID) and return its full detail. Returns: cve_id, description, CVSS (cvss_base_score, cvss_version, cvss_vector, cvss_source), EPSS (epss_score, epss_percentile), CISA KEV status (cisa_kev_added_at), published_at, AI fields (gen_description, gen_cwe_id, gen_impact, gen_mitigations, gen_remediation), and trending metrics (trending_1d/7d/30d). If you only have a name or search terms, call listVulnerabilities first to find the exact identifier. For relationship pivots (e.g. related malware or attack patterns) and advanced cross-entity queries, use queryApi.

NameRequiredDescriptionDefault
identifierYesThe vulnerability identifier — a CVE ID (e.g. CVE-2024-1234) or a UUID.

TDQS

A4.3/5.0
Behavior4/5

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

No annotations are present, so the description carries the full burden, and it does substantial work by enumerating the exact return payload (CVE/CVSS/EPSS/KEV/AI fields/trending) — effectively substituting for the absent output schema. It omits failure behavior (what happens on an unknown or malformed identifier) and any permission/rate-limit notes, which keeps it below a 5.

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?

Front-loaded with the core action, then returns, then alternatives — a logical order with no filler sentences. The return-field enumeration is long, but it is doing real work in place of a missing output schema rather than padding.

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 single-entity read with one parameter and no output schema, the description covers purpose, identifier forms, return shape, and fallback tools. The only meaningful gap is not-found/error behavior and whether the response is cached or rate-limited.

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 already documents the CVE-or-UUID format with an example. The description restates that same constraint without adding syntax, normalization, or validation detail beyond the schema, 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?

States a specific verb and resource ('Fetch a single Mallory vulnerability') plus the accepted identifier forms, and explicitly contrasts itself with listVulnerabilities and queryApi. An agent can pick it out of a 35-tool sibling list without opening the 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?

Gives both routing rules explicitly: if you only have a name or search terms, use listVulnerabilities first; for relationship pivots or cross-entity queries, use queryApi. That covers when to use this tool and the two realistic alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkFindingTicketAInspect

Associate an external ticket (Jira, Linear, GitHub, ServiceNow) with one or more Mallory findings, and manage those associations. Actions: link (register a ticket against findings), attach (add more findings to a ticket already registered here), unlink (remove one finding from a ticket), list (what is linked to a finding), connections (which ticketing systems this tenant has configured).

link, attach and unlink WRITE the caller's own organization's data and take effect immediately — call them only when the user has asked for it. list and connections are read-only; call them whenever you need to know what is linked or what is configured.

TWO STEPS, BOTH REQUIRED. This tool does NOT create the ticket. Create it with the ticketing system's own tools, then call this with action "link" to register the id it returned. A ticket you created and did not register is invisible to Mallory: the finding page shows nothing, and from the user's point of view the request silently did not happen.

A CONFIGURED MALLORY TICKETING INTEGRATION IS NOT A PRECONDITION. With provider + external_id, link is a plain database write inside Mallory — it does not contact the ticketing system. Register the id even when "connections" reports nothing ready; that action answers "which systems can I use?", it does not gate linking, and skipping the link because nothing looked ready is the one failure this tool exists to prevent.

NEVER INVENT external_id, url or title. Core stores all three without checking them, and nothing corrects them later on this path, so a guessed id produces a finding that links to a ticket which does not exist. Send exactly what the provider returned when the ticket was created; omit title or url if you were not given them. url must name the same ticket as external_id — if you are not sure they agree, send external_id alone.

A SUCCESSFUL LINK MEANS MALLORY RECORDED THE ID, nothing more. It does not mean the ticket was found, read or verified. Report what you linked; do not tell the user it was checked.

One ticket often covers several findings: pass every relevant finding_uuid in a single link call rather than linking one at a time. Finding uuids come from listFindings, getFinding, or a createFinding outcome. ticket_uuid (needed by attach and unlink) is Mallory's OWN uuid for a ticket already registered here — it comes from a link outcome or the list action, and is NOT the external id like "MAL-123". Re-linking the same ticket is safe: core upserts.

Unlinking removes only the association in Mallory; the ticket stays in its own system. PLAN_LIMIT means findings are not included in this tenant's plan — the request was fine, nothing is broken and nothing was written: say so and do not retry.

NameRequiredDescriptionDefault
urlNoLink to the ticket in its own system (optional on link). Send it when you have it — it is what the finding page links to. It MUST name the same ticket as external_id: nothing checks that on this path, so a url and an id that disagree are both stored and the finding links somewhere its id does not match. If you are unsure they agree, send only external_id.
titleNoThe ticket's title (optional on link). Send the real title the provider gave you when you created the ticket. Do NOT invent one and do NOT guess: nothing enriches it later on this path, so whatever you send is what the finding page shows forever. Omit it if you do not have it.
actionYesThe operation to perform. Required fields depend on the action: link needs finding_uuids + provider + external_id; attach needs ticket_uuid + finding_uuids; unlink needs ticket_uuid + finding_uuid; list needs finding_uuid; connections takes no other fields.
providerNoWhich ticketing system the ticket lives in (required for link): jira, linear, github or servicenow.
external_idNoThe ticket's id in that system (required for link), e.g. 'MAL-123', 'PROJ-88', or 'owner/repo#42' for GitHub. Use the id the provider returned when the ticket was created. Never guess or construct one: core stores it without checking, so a wrong id produces a finding that links to a ticket which does not exist.
ticket_uuidNoMallory's own uuid for a ticket already registered here (required for attach and unlink). This is NOT the external id — get it from a link outcome or from the list action.
finding_uuidNoA single finding (required for unlink and list).
finding_uuidsNoFindings to associate with the ticket (required for link and attach). One ticket can cover several findings — pass them together rather than calling once each.

TDQS

A4.9/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full behavioral burden and does so thoroughly: it discloses immediate writes, no ticketing-system contact on link, no precondition of a configured integration, no validation of external_id/url/title, upsert safety on re-link, unlink semantics, and PLAN_LIMIT handling. It also correctly frames what a successful link means and does not mean.

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?

Long but appropriately so for a five-action, eight-parameter tool with critical failure modes. It is front-loaded with purpose and action list, then organized into focused warnings about write actions, the required two-step flow, invented ids, success semantics, and batching.

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 no output schema and no annotations, the description covers what an agent needs to call the tool correctly: action-specific required fields, sources for uuids, write-vs-read behavior, link outcome semantics, and error handling. It does not need to document exact return shapes because no output schema exists, and it still gives enough outcome context for safe use.

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 parameters in detail; the description still adds useful workflow semantics, including where finding_uuids come from, how to batch multiple findings, and that ticket_uuid is Mallory's own id rather than an external id. Some of this repeats the schema, but the action-specific guidance and upsert note add value beyond it.

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: associate an external ticketing ticket with Mallory findings, with five named actions. It clearly distinguishes the tool from ticket creation by saying it does not create the ticket and by naming listFindings/getFinding/createFinding as sources for finding uuids.

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 separates write actions (link, attach, unlink) from read-only actions (list, connections) and says to call writes only when the user asked. It also states the required two-step workflow: create the ticket with the provider's own tools, then register it here with action "link".

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAdvisoriesAInspect

List and filter Mallory advisories, returning lean summaries as {items,total,offset,limit}. Each item includes: advisory title/identifier, source/vendor, severity, affected products and vulnerabilities, and published date. Filter prefixes: name:, uuid:. Sort by created_at, updated_at, published_at. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getAdvisory for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations provided, the description carries the transparency burden and does well: it discloses the return envelope, item fields, lean-summary behavior, timestamp range constraints, and the full-detail alternative. It does not explicitly state read-only safety, permissions, or rate limits, but the listing behavior strongly implies a non-mutating read.

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 front-loaded: return shape first, then item contents, filters, sorting, operator rules, and the getAdvisory handoff. Every section contributes directly to correct use, with 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?

There is no output schema and no annotation coverage, so the description compensates by specifying the return shape and item fields as well as filtering and sorting behavior. For a read-oriented list tool, this is complete enough for an agent to invoke it 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?

Schema coverage is already 100%, but the description adds important semantics the schema refers to externally: filter prefixes name: and uuid:, sortable fields, and the timestamp operator restriction. This materially improves correct invocation beyond the schema text 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 states a specific verb and resource: list and filter Mallory advisories. It distinguishes itself from getAdvisory by explaining that this tool returns lean summaries and that an item identifier should be passed to getAdvisory for full details.

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 routes full-detail retrieval to getAdvisory and explains supported filtering and sorting patterns. It does not explicitly compare itself with other list/search siblings such as listVulnerabilities or searchVulnerabilities, so sibling choice guidance is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAttackPatternsAInspect

List and filter Mallory attack patterns, returning lean summaries as {items,total,offset,limit}. Each item includes: mitre_id, name, description, tactic(s), and associated threat actors and malware. Filter prefixes: name:, uuid:, mitre_id:, tactic:. Sort by name, created_at, updated_at. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getAttackPattern for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it discloses the response envelope, the lean-vs-full-detail tradeoff, allowed sort fields, filter prefixes, operator support per type, and the important timestamp restriction (no __gt/__lte/bare equality, half-open ranges only). These are exactly the non-obvious behavioral constraints 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?

Front-loaded with purpose and return shape, then progressively finer detail on filters and operators — well structured with no filler. It does re-state the field-operator rules that also appear verbatim in the fieldFilters schema, a small redundancy that keeps it from a 5.

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?

No output schema exists, yet the description explains the return envelope and item fields, and it fully specifies filtering, sorting, and pagination (limit/offset) semantics. Nothing an agent needs to call this list tool correctly is missing.

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?

Schema coverage is 100%, but the schema defers to the description ("see this tool's sort fields", "see this tool's filter prefixes") and the description actually supplies them: name:/uuid:/mitre_id:/tactic: prefixes, the three sortable fields, and the per-type operator matrix. It adds real meaning the schema alone does not 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?

States a specific verb and resource ("List and filter Mallory attack patterns") plus the exact return shape {items,total,offset,limit}. It explicitly distinguishes itself from getAttackPattern (lean summaries here, full detail there), so an agent can route without opening a schema.

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 final sentence names the alternative: pass an item's identifier to getAttackPattern for the full detail object, which tells the agent when this tool is and isn't the right choice. It stops short of explicit when-not conditions beyond that (e.g., vs. searchEmbeddings or queryApi), so a 4 rather than 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listBreachesAInspect

List and filter Mallory breaches, returning lean summaries as {items,total,offset,limit}. Each item includes: name, description, affected organizations, record_type and loss_type, affected record counts, associated threat actors/malware/attack-patterns, and dates. Filter prefixes: name:, uuid:, loss_type:, record_type:. Sort by created_at, updated_at. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getBreach for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.4/5.0
Behavior4/5

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

No annotations exist, so the description carries the burden and largely does so: it discloses that results are lean summaries, the pagination envelope {items,total,offset,limit}, and a non-obvious constraint that timestamps support only __gte and __lt with no bare equality. It omits permissions, rate limits, and default sort behavior, which keeps it from a 5.

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?

Front-loaded with purpose and return shape, followed by the field/operator details that an agent actually needs at call time. It is dense, and the operator rules appear twice (also in the schema), which is mild redundancy but justified as a correctness guard.

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 six optional parameters, no annotations, and no output schema, the description covers all the gaps: item contents, pagination envelope, sortable fields, filter prefixes, and per-type operator rules. An agent can construct a correct filtered, sorted, paginated call and knows where to go for full detail.

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%, but the schema defers to the description for sort fields and filter prefixes ("see this tool's sort fields"), and the description supplies them: created_at/updated_at plus name:, uuid:, loss_type:, record_type:. It also enumerates operator support per type including the timestamp-only restriction. It does not explain how filter and fieldFilters interact or which field names are valid in filter beyond the listed prefixes.

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 ("List and filter Mallory breaches") and immediately defines the return shape, so the agent knows the exact semantics. The closing pointer to getBreach for full detail clearly separates it from the sibling that fetches a single object.

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?

States the alternative explicitly: use getBreach when you need the full detail object, and use this tool for lean summary listing. It also specifies valid sort fields and filter prefixes, which directs correct invocation. It stops short of explicit exclusions such as when a text search should be done elsewhere, but the routing guidance is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listExploitsAInspect

List and filter Mallory exploits, returning lean summaries as {items,total,offset,limit}. Each item includes: title/name, description, source and maturity, and the vulnerabilities (CVEs) it targets. Filter prefixes: name:, uuid:. Sort by created_at, updated_at. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getExploit for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden well: it discloses the return envelope, item fields, filter prefixes, sortable fields, and an important timestamp-operator limitation. It does not mention permissions or rate limits, but for a read-only list tool that is a minor gap.

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 purpose and return shape are front-loaded, and most sentences earn their place by explaining filtering and sort behavior. It is dense and repeats some operator text already present in the schema, but the size is justified by the tool's filtering complexity.

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?

No output schema exists, but the description fully explains the summary return shape and item fields. It also covers filtering, sorting, pagination via the schema, and the handoff to getExploit, leaving no major ambiguity for calling the 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?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema by naming filter prefixes (name:, uuid:) and sortable fields (created_at, updated_at). It also reinforces the timestamp half-open-range rule, which is relevant to constructing fieldFilters 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?

States a specific verb and resource ("List and filter Mallory exploits") and clearly defines the lean-summary return shape. It also distinguishes the tool from getExploit by explaining that the identifier should be passed there for full detail.

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 says to use this tool for filtered summaries and directs the agent to getExploit when the full detail object is needed. The filter-prefix and sort guidance further clarify expected usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listFindingsAInspect

List and filter Mallory findings, returning lean summaries as {items,total,offset,limit}. Each item includes: title, status, severity, confidence, the owning definition's slug/title/category, asset type and identifier, resolution_reason, the thread_uuid of the investigation that produced it, and timestamps; the detail object adds body / summary / remediation / evidence, any linked external tickets, and entities — the threat actors, vulnerabilities and stories this finding resolved to, which is the pivot back into Mallory's intel graph. Returns every status by default — pass status=open (or status__in=open,fixed) to narrow. Sort by created_at, updated_at, status, title, severity, or asset_identifier; severity sorts INFO < LOW < MEDIUM < HIGH < CRITICAL, so desc puts Critical first. Notable fieldFilters: status, severity, definition_slug, definition_category, asset_type, asset_identifier, title, resolution_reason (also resolution_reason__isnull=true for closed findings with no reason recorded), thread_uuid to scope to one investigation. Enum values are case-sensitive and each field has its own set: severity is UPPERCASE (CRITICAL, HIGH, MEDIUM, LOW, INFO); status is lowercase and has exactly three values (open, fixed, dismissed); resolution_reason is lowercase and separate from status (false_positive, accepted_risk, not_applicable, duplicate, fixed_externally, other); definition_category is lowercase-hyphenated (e.g. public-exposure). Send values, not enum member names. definition_category is the exception: equality and membership ONLY (bare, __in, __not_in) — the __contains/__ilike/__neq the other fields accept are dropped on it, and you get the unfiltered list back. asset_type is a free-text column in provider.service.object form (e.g. aws.s3.bucket, not s3), so a partial value matches nothing unless you use asset_type__ilike. Field operators append to a field name with __: a bare field name is exact match, and the string/enum fields (status, severity, title, definition_slug, asset_type, asset_identifier, resolution_reason) also take __neq, __in, __not_in, __contains, __not_contains, __ilike. This endpoint has NO __like. Timestamps are created_at / updated_at with __gte and __lt ONLY, a half-open range — __gt, __lte and a bare created_at are not parameters at all. An operator this endpoint does not define is dropped silently rather than rejected, so guessing one returns a WIDER result set that looks filtered. Pass an item's identifier to getFinding for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoFull-text search over the finding's title, asset identifier, body, summary, remediation and asset details. Supports web-search query syntax, and AND-combines with the other filters.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: a bare field name is exact match, and the string/enum fields (status, severity, title, definition_slug, asset_type, asset_identifier, resolution_reason) also take __neq, __in, __not_in, __contains, __not_contains, __ilike. This endpoint has NO __like. Timestamps are created_at / updated_at with __gte and __lt ONLY, a half-open range — __gt, __lte and a bare created_at are not parameters at all. An operator this endpoint does not define is dropped silently rather than rejected, so guessing one returns a WIDER result set that looks filtered.

TDQS

A4.6/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full burden — and it discloses the non-obvious behaviors that would otherwise cause silent wrong results: undefined operators are dropped rather than rejected ('guessing one returns a WIDER result set that looks filtered'), definition_category silently ignores __contains/__neq, and timestamps only accept __gte/__lt. Enum case-sensitivity per field and the severity sort ordering are also spelled out. Auth/rate-limit details are absent, but for a read-only listing endpoint the operationally risky behaviors are covered.

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?

Purpose, return shape and the getFinding pointer are front-loaded, which is good. However, the description is one dense block that restates verbatim what the fieldFilters schema description already covers (operator list, no __like, silent-drop warning, timestamp operator limits), so a meaningful fraction of the text does not earn incremental 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?

There is no output schema, so the description must explain return values — and it does, itemizing both the summary fields and the detail object (body/summary/remediation/evidence, linked tickets, and the `entities` pivot into the intel graph). Combined with the pagination envelope and sort semantics, an agent has everything needed to call and interpret this tool.

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?

Schema coverage is 100%, so baseline is 3 — but the description goes well beyond it, enumerating the actual enum value sets (status has exactly three values; severity UPPERCASE values; resolution_reason's six values), the per-field operator availability, the asset_type free-text provider.service.object form, and the notable fieldFilters including thread_uuid. This is precisely the information the opaque `additionalProperties: string` map and the string-typed `sort` cannot convey.

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 (list and filter Mallory findings) and immediately states the return shape {items,total,offset,limit} plus what each item contains. It also distinguishes itself from getFinding ('Pass an item's identifier to getFinding for the full detail object'), so an agent can separate the lean-list tool from the detail tool without opening either schema.

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 states the default behavior ('Returns every status by default — pass status=open ... to narrow') and names the alternative for full detail (getFinding). It does not compare against adjacent list/search siblings such as searchVulnerabilities, but for a filter-heavy list endpoint the usage context is otherwise clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listMalwareAInspect

List and filter Mallory malware, returning lean summaries as {items,total,offset,limit}. Each item includes: name/display_name plus aliases, description, capabilities, family, associated threat actors and ATT&CK techniques, related vulnerabilities, and trending activity. Filter prefixes: name:, uuid:, desc:. Sort by name, created_at, updated_at, enriched_at, or trending / trending_<m|h|d>. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getMalware for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.5/5.0
Behavior4/5

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

No annotations exist, so the description must disclose behavior itself, and it does: the response is a lean summary with a named envelope and an enumerated field list, and the exact filter/sort grammar is spelled out. Gaps remain on permissions, rate limits, and whether results are cached or eventually consistent — but the shape of the operation is fully legible.

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?

Front-loaded and dense with no filler — scope first, then fields, then filtering, then the getMalware handoff. The operator-grammar block is reproduced almost verbatim from the fieldFilters schema description, which is redundant, and the single long paragraph would read better segmented.

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 no output schema, and the description compensates by naming the envelope and enumerating the item fields, so an agent knows what comes back. For a six-parameter filtered-list tool with a nested fieldFilters object, the description leaves nothing essential unstated.

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?

Despite 100% schema coverage, the description adds meaning the schema lacks: concrete filter prefixes (name:, uuid:, desc:), the valid sort keys including the trending_<N><m|h|d> syntax, and the non-obvious constraint that timestamps accept only __gte and __lt with a half-open range pattern. That last point is exactly the kind of trap an agent would otherwise fall into.

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?

"List and filter Mallory malware" is a specific verb plus resource, and the response envelope is stated outright as {items,total,offset,limit}. The final sentence explicitly contrasts it with getMalware, so an agent can separate the list path from the detail path without opening a schema.

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?

"Pass an item's identifier to getMalware for the full detail object" gives an explicit alternative and the condition that selects it. It does not address when to reach for other list* siblings or when prefix search should win over fieldFilters, but the primary routing decision is covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listObservablesAInspect

List and filter Mallory observables, returning lean summaries as {items,total,offset,limit}. Each item includes: observable type (e.g. ip.v4, domain, url, hash.sha256), name/value, and verdict/opinion counts. Filter prefixes: type: (e.g. type:ip or type:ip.v4), name:, uuid:. Sort by uuid, created_at, updated_at, type, name, severity_score, confidence_score. Optional fieldFilters: scope=global|tenant, created_at__gte/__lt, severity_score__gte/__lte, confidence_score__gte/__lte, score_scope=tenant|global (tenant: only observables with the tenant's custom score). Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getObservable for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the full load and does substantial work: it discloses the return envelope {items,total,offset,limit}, the fields per item, filter prefixes, sortable fields, and the non-obvious constraint that timestamps support only __gte/__lt (no bare equality). It omits auth/tenant-permission requirements and error behavior, so it is strong but not complete.

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?

Front-loaded with purpose and return shape, then progressively detailed syntax. The operator rules are dense but each sentence conveys a distinct constraint. It reads as one long block rather than segmented, which slightly hurts scannability, but there is little filler.

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?

No output schema exists, and the description compensates by describing the response envelope and item fields. Given 6 optional parameters and nested fieldFilters, the filtering model is well-covered. Missing only operational context such as tenant scoping behavior by default and error/pagination edge cases.

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?

Schema coverage is 100% (baseline 3), but the description goes well beyond the schema, which only says 'see this tool's sort fields' and 'see this tool's filter prefixes.' It actually enumerates the sort fields, the filter prefixes (type:, name:, uuid:), the fieldFilters scope/score_scope values, and the full operator matrix with the timestamp exception — real 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?

States a specific verb and resource (list/filter Mallory observables) and immediately gives the concrete item shape (type, name/value, verdict/opinion counts), which distinguishes it from get*, which returns the full detail object. The final sentence explicitly hands off to getObservable, so an agent can route without opening a schema.

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?

Clear context for use (bulk listing with filtering/sorting/pagination) and an explicit alternative: 'Pass an item's identifier to getObservable for the full detail object.' It does not state when-not-to-use or mention permissions/prerequisites, so it falls short of 5, but the sibling routing is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listOrganizationsAInspect

List and filter Mallory organizations, returning lean summaries as {items,total,offset,limit}. Each item includes: name, description, associated products and breaches, and mention activity. Filter prefixes: name:, uuid:. Sort by name, created_at, updated_at. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getOrganization for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.3/5.0
Behavior4/5

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

No annotations are provided, so the description carries the burden, and it does disclose the response envelope, what each item contains, and a non-obvious constraint (timestamps only accept __gte/__lt, no bare equality). It omits permissions, rate limits, and behavior on invalid filter operators.

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?

Front-loaded with purpose and return shape before the denser operator rules; every sentence carries usable information. The operator enumeration is repeated nearly verbatim from the schema, which is slight 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?

With no output schema, the description correctly explains the return envelope and per-item fields, plus filtering, sorting, and the detail-object handoff. Good coverage for a 6-param list tool; pagination interaction between offset/limit and total is implied but not spelled 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 baseline is 3, but the description adds real meaning the schema defers on: filter prefixes name: and uuid:, the allowed sort fields, and the half-open range idiom for timestamps. It doesn't explain how filter and fieldFilters interact or precedence rules.

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 (list and filter organizations) and immediately defines the return shape ({items,total,offset,limit}) plus item contents. It also routes full-detail lookups to getOrganization, distinguishing it cleanly from that sibling.

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 directs the agent to getOrganization for full detail objects, which is a genuine use-vs-alternative rule. It doesn't cover exclusions or prerequisites (auth, scoping), so it stops 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.

listProductsAInspect

List and filter Mallory products, returning lean summaries as {items,total,offset,limit}. Each item includes: vendor and product name, CPE, description, and links to advisories and vulnerabilities. Filter prefixes: name:, uuid:. Sort by name, created_at, updated_at. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getProduct for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the exact response envelope, pagination fields, supported sort fields, and the unusual timestamp-operator restriction (only __gte and __lt, half-open ranges). It omits any mention of permissions/auth or result caps beyond the schema's limit bounds, so it stops short of a 5.

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?

Front-loaded with purpose and return shape, then filtering and operator rules in a logical order; nearly every sentence adds usable detail. The operator-rule sentence is largely duplicated in the fieldFilters schema description, which is wasted repetition for a definition this dense.

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?

Six parameters, a nested fieldFilters object, and no output schema — yet the description fully specifies the returned object's fields, pagination keys, sortable fields, and the operator grammar including the timestamp special case. Nothing essential to calling it correctly 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 baseline would be 3, but the description adds information the schema defers on: the concrete filter prefixes (name:, uuid:), the allowed sort fields (name, created_at, updated_at), and the operator matrix with the timestamp exception. That meaningfully compensates for the schema's "see this tool's filter prefixes" placeholder.

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 ("List and filter Mallory products") plus the return shape, and explicitly separates itself from the getProduct sibling ("Pass an item's identifier to getProduct for the full detail object"). An agent can distinguish list-vs-detail without opening either schema.

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 routes the agent to getProduct when full detail is needed, which is the key decision for a list tool. It does not discuss when to prefer siblings like findAffectedProducts or listVulnerabilities, so usage guidance is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSoftwareExtensionsAInspect

List and filter Mallory software extensions, returning lean summaries as {items,total,offset,limit}. Each item includes: extension name, marketplace/ecosystem, publisher, install count, description, and known configurations. Filter prefixes: name:, uuid:. Sort by created_at, updated_at, install_count. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getSoftwareExtension for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does disclose real behavioral traits: results are 'lean summaries' rather than full objects, the item field set, and the notable constraint that timestamps support only __gte/__lt with a half-open range idiom. Auth requirements and rate limits are not mentioned, keeping it below a 5.

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?

Front-loads the return shape and item fields before the filtering mechanics, which is the right order for a list tool. The operator list is repeated almost verbatim from the fieldFilters schema, so there is some redundancy, 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?

No output schema exists, so the description explains the return envelope and item contents itself. With six parameters including a nested free-form filter map, it covers pagination, sort, prefix search, and structured operators well enough to call the tool correctly first time.

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 defers to the description for the actual values ('see this tool's sort fields', 'see this tool's filter prefixes'), and the description supplies them: name:/uuid: prefixes, sortable fields created_at/updated_at/install_count, and the full operator matrix. This is genuine compensation, not restatement.

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 ('List and filter Mallory software extensions') plus the exact return envelope {items,total,offset,limit}. It also separates itself from the detail sibling by naming getSoftwareExtension for the full object, so an agent can choose without opening a schema.

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 routes the agent to getSoftwareExtension when full detail is needed, and the filter section clarifies that no prefix means a default name/text search. It does not state exclusions beyond that one routing rule, so it falls just short of a full when/when-not treatment.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSoftwarePackagesAInspect

List and filter Mallory software packages, returning lean summaries as {items,total,offset,limit}. Each item includes: package name, ecosystem, description, known configurations, and supply-chain compromise evidence. Filter prefixes: name:, uuid:. Sort by created_at, updated_at, last_compromised_at, or compromise_evidence_count. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getSoftwarePackage for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.8/5.0
Behavior4/5

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

With no annotations, the description carries the full behavioral burden. It discloses the return envelope, item fields, filtering constraints, and the important timestamp-operator limitation, but does not discuss permissions, rate limits, or explicit read-only safety, which are minor gaps for a list operation.

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 front-loaded and every sentence adds operational value. Given the complexity of the filtering syntax, the length is appropriate 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?

There is no output schema, but the description defines the return shape as {items,total,offset,limit} and lists what each item includes. Combined with the filtering and sorting rules, it is complete enough for an agent to call the tool 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?

Schema coverage is 100%, so the baseline would be 3, but the description adds substantial semantic detail beyond the schema: filter prefixes name: and uuid:, allowed sort fields, field operator behavior, and the restricted timestamp operators with a half-open range example.

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 and filter Mallory software packages. It clearly distinguishes the lean list output from the full detail object returned by getSoftwarePackage, so an agent can distinguish it from siblings 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?

It explicitly routes the agent to getSoftwarePackage when an item identifier is available and the full detail object is needed. It also explains filter prefixes, sort fields, and operator behavior, leaving little ambiguity about how to use the tool versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listThreatActorsAInspect

List and filter Mallory threat actors, returning lean summaries as {items,total,offset,limit}. Each item includes: canonical name/display_name plus aliases, description, motivation, sponsor, family, targeted industries and source/target geographies, and trending activity. Filter prefixes: name:, uuid:, internal_name:, desc:. Sort by name, created_at, updated_at, enriched_at, or trending / trending_<m|h|d> (e.g. trending_7d). Notable fieldFilters: motivation, sponsor, family_name. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getThreatActor for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations present, the description carries the full disclosure burden and meets it: it defines the response envelope {items,total,offset,limit}, enumerates the per-item fields returned, and specifies sort and filter capabilities including a hard constraint that timestamps support only __gte and __lt with no bare equality. This is exactly the kind of behavioral detail an agent cannot get from the structured fields.

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?

Front-loaded with purpose and return shape, then drill-down details in a logical order. It is dense with zero filler sentences, though the operator enumeration is repeated verbatim from the fieldFilters schema description and could have been trimmed to a reference.

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 no output schema, and the description compensates by describing the exact response envelope and item contents. For a six-parameter, nested-filter list tool with no annotations, everything an agent needs to call it correctly — sort fields, prefix syntax, operator limits, pagination — is present.

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 baseline is 3, but the description adds value the schema defers on — it enumerates concrete sort fields (name, created_at, updated_at, enriched_at, trending_<N><m|h|d>) and filter prefixes (name:, uuid:, internal_name:, desc:), and calls out notable fieldFilters keys. The operator semantics text duplicates the fieldFilters schema description verbatim rather than adding to it, which keeps this from a 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?

States a specific verb and resource ("List and filter Mallory threat actors") and immediately distinguishes itself from the sibling getThreatActor by noting this returns lean summaries and that full detail requires the item identifier. An agent can route between the two without opening either schema.

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 routes heavy-detail lookups to getThreatActor ("Pass an item's identifier to getThreatActor for the full detail object"), which is a clear when-to-use-the-other-tool rule. It lacks an explicit when-not clause (e.g., don't use this for bulk exports or cross-entity search), but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listVulnerabilitiesAInspect

List and filter Mallory vulnerabilities, returning lean summaries as {items,total,offset,limit}. Each item includes: cve_id, description, CVSS (cvss_base_score, cvss_version, cvss_vector, cvss_source), EPSS (epss_score, epss_percentile), CISA KEV status (cisa_kev_added_at), published_at, AI fields (gen_description, gen_cwe_id, gen_impact, gen_mitigations, gen_remediation), and trending metrics (trending_1d/7d/30d). Filter prefixes: cve:, uuid:, desc:, gen_description:, gen_name:. Sort by cvss_base_score, epss_score, epss_percentile, published_at, created_at, updated_at, trending_1d/7d/30d. Range-filter via fieldFilters, e.g. {"cvss_base_score__gte":"9"} or {"published_at__gte":"2024-01-01"}. Field operators append to a field name with __: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=&created_at__lt=. Pass an item's identifier to getVulnerability for the full detail object.

NameRequiredDescriptionDefault
sortNoField to sort by (see this tool's sort fields).
limitNoMax items to return (1-100, default 25).
orderNoSort order (default: desc).
filterNoPrefix filter string (see this tool's filter prefixes). No prefix = default name/text search.
offsetNoItems to skip, for pagination.
fieldFiltersNoAdvanced structured filters as a map of query-param name -> value. Use a bare field for exact match, or a field__operator key for ranges/sets. Field operators append to a field name with `__`: strings support __neq, __in, __not_in, __like, __ilike; numbers support __gt, __gte, __lt, __lte. Timestamps (created_at, updated_at) support __gte and __lt ONLY — there is no __gt, __lte, or bare equality on them, so express a range as the half-open created_at__gte=<start>&created_at__lt=<end>.

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does disclose important behavioral details: lean summary output, field names, supported sort fields, filter prefixes, and the unusual timestamp operator constraint. It does not mention authorization requirements, rate limits, or explicitly state read-only behavior, but the list/summary framing strongly implies a safe read operation.

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 purpose and return shape, then moves into filter and sort details in a logical order. It is dense and mostly earns its length, though some operator text duplicates what already appears in the fieldFilters schema description, which makes it slightly longer than strictly necessary.

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 no output schema, so the description appropriately explains the returned envelope and item fields. It also covers filtering, sorting, field operators, and the key timestamp range caveat, which is complete context for a six-parameter list/filter tool.

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?

Schema coverage is already 100%, but the description adds substantial meaning beyond the schema by naming sortable fields, filter prefixes, supported field operators, and concrete range-filter examples. The timestamp restriction is especially valuable because it prevents the agent from constructing unsupported filters.

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 and filter Mallory vulnerabilities'—and immediately clarifies the return shape as lean summaries rather than full objects. It also explicitly routes full-detail retrieval to getVulnerability, so the agent can distinguish this listing tool from the detail tool without opening the schema.

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 context for using this tool when the goal is a filtered vulnerability list, and it names getVulnerability as the alternative for full detail. However, it does not explicitly differentiate this tool from searchVulnerabilities, which is another plausible sibling, leaving some ambiguity about when semantic search should be preferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryApiAInspect

Query the Mallory cybersecurity-intelligence API. Two input fields:

  • "path": an endpoint under /v1/ (e.g. "/v1/vulnerabilities", "/v1/actors/APT29/attack_patterns"). You can ALSO paste a Mallory web URL or path here (e.g. "https://app.mallory.ai/vulnerabilities/CVE-2025-43300", "/actors/{uuid}", "/attack-patterns/T1566", "/references/{uuid}") — it's auto-translated to the matching API endpoint, so you never need to know the URL→API mapping.

  • "queryParams": object of string key->value pairs for filtering, sorting, pagination

PREFER the named per-entity tools when they fit: get to fetch one by id (e.g. getVulnerability, getThreatActor, getMalware, getObservable) and list to filter many (e.g. listVulnerabilities, listThreatActors). Use THIS tool as the fallback for what they don't express: relationship pivots (e.g. /v1/actors/APT29/malware), cross-entity search (/v1/search), structured field filters and numeric/date ranges, or any endpoint they don't cover. You can also paste a Mallory web URL as the path.

DATA DOMAINS (first path segment): vulnerabilities, actors (threat actors), malware, exploits, exploitations, breaches, attack_patterns (MITRE ATT&CK), products, organizations, observables, references, stories, advisories, detections, weaknesses (CWE), industries, packages, opinions, mentions, search.

COMMON PATTERNS: List + filter: path="/v1/vulnerabilities" queryParams={"filter":"cve:CVE-2024","sort":"cvss_base_score","order":"desc","limit":"10"} Relationships: path="/v1/actors/APT29/malware" | path="/v1/vulnerabilities/CVE-2024-1234/threat_actors" Cross-entity: path="/v1/search" queryParams={"q":"ransomware","types":"threat_actor,malware","limit":"10"} Compromised pkgs: path="/v1/packages" queryParams={"sort":"last_compromised_at","order":"desc","limit":"20"} — recently compromised packages, newest first (use sort=compromise_evidence_count for most-compromised by count). Drill in via path="/v1/packages/{uuid}/compromises" (sorts by reported_at desc; optional compromise_type: malicious_version, account_takeover, typosquat, dependency_confusion, backdoor, supply_chain, other).

FILTER PREFIXES (inside the "filter" param; which apply depends on the endpoint): cve:, uuid:, name:, desc:, gen_name:, gen_description:, mitre_id:, tactic:, loss_type:, record_type:. No prefix = default text/name search.

FIELD OPERATORS (append to a field name with "__"): strings: __neq, __in, __not_in, __like, __ilike (case-insensitive) numbers: __neq, __gt, __gte, __lt, __lte e.g. {"cvss_base_score__gte":"9"} timestamps: __gte, __lt with ISO-8601 values e.g. {"published_at__gte":"2024-01-01"}

CVSS Vector filtering (/v1/vulnerabilities)

CVSS vector filters: cvss=AV:A/PR:N matches all slash-separated tokens within one stored assessment; cvss__in=AV:A,AV:N matches any comma-separated fragment. Both search across CVSS 2.0, 3.0, 3.1, and 4.0 assessments; prefix a fragment with CVSS:3.1/ to restrict its version. Metric names and values are case-sensitive (v2 Au differs from v4 AU), and only explicitly stored metrics match. These filters do not change the selected numeric cvss_base_score. CVSS CEL: where='cvss == "AV:A/PR:N" && epss_score >= 0.5' supports ==, !=, in, AND/OR/NOT. Keep tokens in one fragment for same-assessment AND; separate CVSS comparisons may match different assessments. Invalid fragments return HTTP 400: correct the requested filter, never retry without it.

HUNTING: Actor/malware indicator_context summarizes global plus current-tenant intelligence for the resolved observable, not an actor-specific edge; tags/roles honor requested scope. Missing context and dates/roles remain unknown. source_count does not count independent investigations. Correct a rejected filter without dropping the user's selection. Array-typed queryParams accept CSV except /v1/observables tag, whose commas are literal; repeat inline tag parameters for multiple exact values. Repeated inline array parameters retain all values.

PAGINATION/SORT: "limit" (follow the endpoint's documented bound), "offset", "sort":"", "order":"asc"|"desc".

RESPONSE: results come back as {"data": , "meta": {"endpoint","path"}}. For list / search / relationship endpoints "data" is the list envelope {"data":[...items], "total", "offset", "limit"} (items live at data.data); for a single-entity path "data" is the entity object. List responses are returned whole, exactly as the API paged them — control size with limit/offset. Semantic entity queries return an exact integer total, but descending similarity pages without a cutoff are approximate; a 503 means semantic search is temporarily unavailable (a provider failure or a very broad query timing out), never that nothing matched. Invalid, blocked, or unknown paths return a tool error (isError), not a result.

Repository data availability: An empty resolved inventory, current=null, or an unavailable inventory tool does not mean the tenant has no repositories or vulnerabilities. Check connected integrations and whether they cover the requested data. If resolved inventory lacks that coverage and an authorized integration-data transport is available, continue with connected-source data: in the in-app sandbox, load the steampipe-querying skill, discover tables for the connected provider, and use its structured query workflow (cache first; live when uncached or current state is required). Preserve existing filters and repository scope, and report source freshness and coverage differences. If this client has no such transport or no relevant integration is connected, state the coverage limitation; never substitute global threat intel for tenant evidence. Do not bypass permission denials. Offer Mallory asset-page links only when that UI is enabled for the caller; otherwise use a source-provided repository URL when available.

Note: schedule management (/v1/schedules) is not exposed over MCP in V1. Every other endpoint is scoped by your API key to your own tenant.

NameRequiredDescriptionDefault
pathYesAn endpoint path under /v1/ (e.g. /v1/vulnerabilities, /v1/actors/APT29/attack_patterns), OR a Mallory web URL/path you can paste directly (e.g. https://app.mallory.ai/vulnerabilities/CVE-2025-43300, /actors/{uuid}, /attack-patterns/T1566, /references/{uuid}) — pasted links are auto-translated to the matching API endpoint.
queryParamsNoQuery parameters for filtering, sorting, and pagination. Pass as {"key":"value"} pairs, e.g. {"filter":"cve:CVE-2024","limit":"10","sort":"cvss_base_score"}. For array parameters, use comma-separated values here (e.g. {"types":"vulnerability,exploit"}), except /v1/observables tag: commas stay literal, and multiple tags require repeated inline tag keys. Explicit values replace all inline values for that key. Pass {} if no params needed.

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it documents the response envelope shape ({data, meta} and the nested list envelope at data.data), pagination behavior (whole responses, limit/offset control), error semantics (isError for invalid/blocked paths, 400 on bad CVSS fragments, 503 meaning semantic search unavailability rather than no match), tenant scoping by API key, and that /v1/schedules is not exposed. It also flags permission denials and integration-coverage caveats that an agent would otherwise misread as empty data.

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?

Front-loaded and decently sectioned (DATA DOMAINS, COMMON PATTERNS, FILTER PREFIXES, PAGINATION, RESPONSE), but it is very long and mixes core invocation guidance with tangential passages — the HUNTING paragraph and especially the repository-data-availability block read as system-prompt material rather than tool documentation, adding bulk an agent must wade through.

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 maximally broad pass-through tool with no output schema, the description covers what is needed to call it correctly: endpoint taxonomy, worked examples, filtering/operator grammar, pagination, response shape, and failure modes. Nothing essential to a successful or correctly-interpreted call is missing.

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?

Although schema coverage is 100% (baseline 3), the description goes far beyond it: it enumerates filter prefixes (cve:, mitre_id:, tactic:, etc.), the full __ operator set per type with examples, CSV-vs-inline array semantics for queryParams, the /v1/observables tag comma exception, and detailed CVSS vector/CEL matching rules including case-sensitivity and version scoping. This is meaning the schema cannot express.

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 (query the Mallory cybersecurity-intelligence API via a /v1/ path plus queryParams) and immediately defines its role relative to the named per-entity siblings. An agent can distinguish this generic escape hatch from getVulnerability/listThreatActors 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?

Explicit when-to-use and when-not-to-use: 'PREFER the named per-entity tools when they fit' with the exact fallback conditions enumerated (relationship pivots, cross-entity search, structured field filters, numeric/date ranges, uncovered endpoints). It also names the concrete alternatives (get<Entity>, list<Entity>) and gives worked path examples for each fallback case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

referenceObservablesAInspect

Get the indicators of compromise (IOCs / observables — IPs, domains, URLs, file hashes, email addresses, etc.) that Mallory extracted and attributed from a specific reference (source document). This is the 'reference → IOCs' pivot: given a threat report, return the concrete indicators it contains, so you don't have to scrape them from the report text. Provide reference as a UUID, url_hash, or a pasted Mallory reference URL. If you only have the article's web URL, first resolve it to a reference with getReference (urlFilter mode).

NameRequiredDescriptionDefault
limitNoMaximum number of observables to return (max 500).
offsetNoNumber of observables to skip, for pagination.
referenceYesA reference UUID, url_hash, or a pasted Mallory reference URL (e.g. 'https://app.mallory.ai/references/{uuid}').

TDQS

A4.4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses the data provenance ('Mallory extracted and attributed') and the practical benefit (no manual scraping), which is genuine behavioral context, but says nothing about permissions, rate limits, whether results are cached/stale, or what an empty result means. Adequate but not rich for an annotation-free tool.

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, front-loaded with the verb/resource and the pivot concept, then the accepted input forms, then the fallback routing. Every sentence carries distinct information with no repetition of the name or title.

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 no output schema, the description should signal what comes back; it does so conceptually by enumerating indicator types but not the actual result fields or envelope. Inputs, scoping, and the URL-resolution prerequisite are all covered, making it sufficient to call correctly though slightly thin on return shape.

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 would be 3. The description nevertheless adds one non-obvious constraint absent from the schema: a plain article web URL is not an accepted value and must be resolved via getReference first, which prevents a common malformed call. It does not elaborate on limit/offset, but the schema already documents those fully.

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 verb (get) and resource (IOCs/observables) and states the exact scope: observables attributed to a single reference. The 'reference → IOCs pivot' framing, plus the enumerated indicator types (IPs, domains, URLs, hashes, emails), makes it immediately distinguishable from getObservable, listObservables, and getReference.

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 the positive case (given a threat report, get its indicators without scraping text) and an explicit prerequisite path: if only a web URL is available, call getReference in urlFilter mode first. That names the alternative sibling and the condition that selects it, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

searchEmbeddingsAInspect

Search the MalloryAI knowledge base using semantic similarity. This searches across all indexed cybersecurity content including articles, reports, and documentation. Use this to find relevant information about security concepts, vulnerabilities, threat intelligence, and best practices.

NameRequiredDescriptionDefault
limitNoMaximum number of results to return
queryYesSearch query for cybersecurity knowledge and information

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It usefully discloses that matching is semantic rather than keyword and that the index spans articles, reports, and documentation, but says nothing about result ordering, score exposure, or that results are ranked by similarity rather than recency.

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 compact sentences with the action and corpus front-loaded; no filler. Slight redundancy in repeating "searches" / "search" across consecutive sentences, but nothing that needs cutting.

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?

A two-parameter read tool with a fully documented schema and no output schema; the description covers what is searched and why. Only the shape of returned results and their ordering are left implicit, which is a minor gap for a simple search 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 both parameters are documented in-schema, so the baseline of 3 applies. The description adds no parameter-level detail at all — it never mentions limit or how the query string is interpreted for semantic matching.

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?

States a specific verb and resource ("Search the MalloryAI knowledge base using semantic similarity") and defines the corpus as all indexed cybersecurity content. It does not, however, distinguish itself from the sibling searchVulnerabilities, which an agent would reasonably consider an alternative for the same subject matter.

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?

"Use this to find relevant information about security concepts, vulnerabilities, threat intelligence, and best practices" gives a usage context but names no alternative and no exclusion. The mention of "vulnerabilities" actively muddies the choice against searchVulnerabilities, leaving the agent to infer that this tool is the broad fallback.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

searchVulnerabilitiesAInspect

Search and filter vulnerabilities in the MalloryAI database. Supports filtering by CVE ID, UUID, description, and various sorting options including CVSS score, EPSS score, and trending scores. Use this to find specific vulnerabilities, discover trending threats, or analyze vulnerability patterns. Returns comprehensive vulnerability data including: CVE ID, description, CVSS scores (base score, version, vector, source, full CVSS data array), EPSS score and percentile, CISA KEV status, publication dates, AI-generated fields (description, display name, CWE ID, impact assessment, mitigations, remediation), and trending metrics (1d, 7d, 30d).

NameRequiredDescriptionDefault
sortNoField to sort results by (default: published_at)published_at
limitNoMaximum number of results to return
orderNoSort order: ascending or descending (default: desc)desc
filterNoFilter query. Prefixes: 'cve:' for CVE ID, 'uuid:' for UUID, 'desc:' for description, 'gen_description:' for generated description, 'gen_name:' for generated name. No prefix defaults to description search.

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations, the description carries the full burden; it does well on output shape by enumerating the returned fields (CVE, CVSS, EPSS, KEV, AI fields, trending windows) and on sort behavior (default published_at, trending 1d/7d/30d). It is silent on the safety profile (that it is a read-only operation), on authentication/rate limits, and on result-window behavior beyond the limit cap, which are the main behavioral gaps.

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?

Front-loaded with the action and filtering capability, then use cases, then payload. The long return-field enumeration is lengthy but defensible given there is no output schema; no sentence is pure filler.

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?

Since there is no output schema, the detailed return-value list is necessary and present, and the filter/sort behavior is covered. Missing only operational context (read-only nature, auth, pagination semantics) for a zero-required-parameter search tool, which is a modest 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 coverage is 100% and even documents the filter prefix syntax, so the schema does the heavy lifting. The description adds some semantic mapping by naming filter targets (CVE ID, UUID, description) and sort metrics (CVSS, EPSS, trending), but contributes no format or syntax detail beyond what the schema already provides.

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?

States a specific verb+resource ('Search and filter vulnerabilities') and adds scope details (filter fields, sort fields, result payload). It never names or rules out the obvious siblings listVulnerabilities/getVulnerability, so the agent must infer which retrieval tool to pick.

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?

Gives three concrete use cases ('find specific vulnerabilities, discover trending threats, or analyze vulnerability patterns') that map cleanly onto the sort/filter parameters. It provides no when-not conditions and no explicit pointer to listVulnerabilities vs getVulnerability, so routing is clear but not exclusive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateFindingAInspect

Update ONE existing Mallory finding in place — its status, severity, confidence, title, summary, body, remediation, qualifier or asset_details. Use it when new information changes an already-filed finding: the problem was fixed, it turned out not to apply, a vulnerability proved reachable, corroborating intel changes how bad it is.

WRITES IMMEDIATELY to the caller's own organization's data, and the result is visible in the Mallory UI to everyone in that organization. There is no preview and no confirmation step — calling this tool IS the write. Only call it when the user has asked for the change.

  • uuid identifies the finding. Get it from listFindings or getFinding, or from a createFinding DUPLICATE outcome's existing_finding_uuid. Never construct or guess one.

  • ONE finding per call. To change status or severity across a SET of findings you can only describe ("dismiss all the unrotated-secret findings", "mark everything on foo/bar medium"), use bulkUpdateFindings — do NOT loop this tool over a selection.

  • The finding's identity — definition_slug, asset_type, asset_identifier — cannot be changed. A different problem, or the same problem on a different asset, is a new finding (createFinding).

  • body REPLACES the stored text rather than appending to it. To add to a finding, read the current text first with getFinding and send the combined text, or the prior detail is lost. There is no evidence field on update: new evidence goes into body as prose.

  • qualifier is part of core's open-finding dedupe key, so changing it can collide with another open finding on the same asset (CONFLICT).

In user-facing status messages, use "fixed" and "mark as fixed" consistently.

ENUM VALUES ARE CASE-SENSITIVE AND EACH FIELD HAS ITS OWN SET. severity is UPPERCASE (CRITICAL, HIGH, MEDIUM, LOW, INFO). status is lowercase with exactly three values: open, fixed, dismissed — "resolved", "closed" and "assigned" are not statuses, and neither are the resolution reasons (false_positive, accepted_risk, not_applicable, duplicate, fixed_externally, other), which belong to a separate field this tool does not set. Use "fixed" when the problem was remediated and "dismissed" when it is accepted or not applicable. Setting status back to "open" is allowed but unusual — the product has no reopen button — so confirm the user really means to reopen the finding.

OUTCOMES: either ok:true with the updated finding, or ok:false with a code — NOT_FOUND (no such finding in this tenant: do not retry, re-read the uuid), CONFLICT (an open finding already occupies that identity), INVALID (a rejected field, or no fields to change), PLAN_LIMIT (findings are not included in this tenant's plan — the request was fine, nothing is broken, nothing was written: say so and do not retry).

NameRequiredDescriptionDefault
bodyNoThe detail: what was found, how, and why it matters. Rendered as markdown. REPLACES the existing body — when adding to a finding (e.g. why it was escalated), read the current body first and send the combined text, or the prior detail is lost.
uuidYesUUID of the finding to update. Comes from a create outcome's existing_finding_uuid, or from GET /v1/findings.
titleNoAsset-scoped headline. Omit unless it is genuinely wrong.
statusNoLifecycle state. 'fixed' when the underlying problem is fixed, 'dismissed' when it is accepted or not applicable.
summaryNoOne or two sentences: what is wrong. Rendered as markdown.
severityNoNew severity for this instance, e.g. when reachability or corroborating intel changes how bad it is. Overrides the definition's default.
qualifierNoDiscriminator when one asset has several instances of the same definition. Part of the dedupe key — changing it can collide with another open finding (409).
confidenceNo
remediationNoConcrete steps to fix it, ideally a runnable command. Rendered as markdown.
asset_detailsNoFree-form structured context about the asset (region, account, owner, ...). Replaces the stored object.

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations, the description carries the full load and does so: it states the write is immediate with no preview or confirmation, that changes are visible org-wide, that body/asset_details replace rather than merge, and that qualifier edits can collide via the dedupe key. The outcome codes (NOT_FOUND, CONFLICT, INVALID, PLAN_LIMIT) with retry guidance go well beyond what annotations would have provided.

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?

Front-loaded with the purpose, then side-effects, then per-field rules, then outcomes — a sensible escalation. It is long, and the enum casing paragraph partly restates what the schema enums already encode, which costs some conciseness, but nearly every sentence carries operational 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 10-parameter mutation tool with no annotations and no output schema, the description covers everything load-bearing: immutability of identity fields, dedupe collisions, replacement-vs-append semantics, the status vocabulary trap, and the full failure taxonomy including the non-retryable PLAN_LIMIT case.

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?

Schema coverage is already 90%, yet the description still adds real semantics: where uuid may and may not come from, that body replaces (with the getFinding read-then-merge workaround), that qualifier is part of the dedupe key, and that resolution reasons are a different field from status. It also flags the case-sensitivity of the differing enum casings.

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 and resource ('Update ONE existing Mallory finding in place') and enumerates the mutable fields. It explicitly separates itself from bulkUpdateFindings and createFinding, so an agent can route correctly without reading sibling 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?

Gives an explicit trigger ('when new information changes an already-filed finding'), an explicit permission gate ('Only call it when the user has asked for the change'), and named alternatives: bulkUpdateFindings for describable sets and createFinding for new problems or new assets. It even forbids the anti-pattern of looping this tool.

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.

  1. 36 tool updates
    • First observedbulkUpdateFindings
    • First observedcreateFinding
    • First observedfindAffectedProducts
    • First observedgetAdvisory
    • First observedgetAttackPattern
    • First observedgetBreach
    • First observedgetExploit
    • First observedgetFinding
    • First observedgetMalware
    • First observedgetObservable
    • First observedgetOrganization
    • First observedgetProduct
    • First observedgetReference
    • First observedgetSoftwareExtension
    • First observedgetSoftwarePackage
    • First observedgetThreatActor
    • First observedgetVulnerability
    • First observedlinkFindingTicket
    • First observedlistAdvisories
    • First observedlistAttackPatterns
    • First observedlistBreaches
    • First observedlistExploits
    • First observedlistFindings
    • First observedlistMalware
    • First observedlistObservables
    • First observedlistOrganizations
    • First observedlistProducts
    • First observedlistSoftwareExtensions
    • First observedlistSoftwarePackages
    • First observedlistThreatActors
    • First observedlistVulnerabilities
    • First observedqueryApi
    • First observedreferenceObservables
    • First observedsearchEmbeddings
    • First observedsearchVulnerabilities
    • First observedupdateFinding

Publisher details

Operator
Mallory · Publisher source
Vendor relationship
Not applicable
Restrictions
Not applicable

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Remote MCP server that lets AI assistants read tracked competitive intelligence — competitor news, reviews, website changes, social posts and ads — and act on it by managing projects, competitors, battle cards, reports and canvases. Every answer carries a source and a date, and write actions only publish when explicitly shared.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables brand visibility monitoring across major AI platforms like ChatGPT, Claude, Gemini, and Perplexity. It allows users to track visibility scores, analyze competitor data, and receive actionable insights to improve AI-generated brand recommendations.
    16
    18 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Browse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources