Skip to main content
Glama

Server Details

Query FDA data on drugs, food, devices, and recalls via openFDA. STDIO or Streamable HTTP.

If you are the author of this connector, you can claim ownership with GitHub, an HTTP challenge, or a DNS record. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Last Tested
Transport
Streamable HTTP
URL
Repository
cyanheads/openfda-mcp-server
GitHub Stars
4
Server Listing
@cyanheads/openfda-mcp-server

Available Tools

14 tools
openfda_count_valuesOpenfda Count ValuesA
Read-only
Inspect

Aggregate and tally unique values for any field across any openFDA endpoint. Returns ranked term-count pairs sorted by count descending. Pair with openfda_search_adverse_events, openfda_search_drug_approvals, openfda_search_device_clearances, openfda_search_recalls, openfda_get_drug_label, or openfda_lookup_ndc when sample records help interpret the aggregates.

ParametersJSON Schema
NameRequiredDescriptionDefault
countYesField to count. Append .exact for whole-phrase counting of free-text fields (e.g. "patient.reaction.reactionmeddrapt.exact"). Identifier fields openFDA already indexes as keywords (product_ndc, application_number, pma_number) must be counted bare — .exact on those is rejected as not countable.
limitNoNumber of top terms to return (default 100, max 1000)
searchNoFilter query to scope the count (e.g. patient.drug.medicinalproduct:"metformin"). Omit to count across every record in the endpoint. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
endpointYesFull openFDA endpoint path (e.g. "drug/event", "device/classification")

Output Schema

ParametersJSON Schema
NameRequiredDescription
capNoThe limit applied to the term list.
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
shownNoNumber of terms returned in this response.
noticeNoGuidance when no terms matched — how to verify the field name or adjust the count expression. Absent when terms are returned.
resultsNoTerm-count pairs sorted by count descending
termCountNoNumber of distinct terms returned
truncatedNoTrue when the term list was capped at the limit — more distinct terms may exist.
truncationCeilingNoCount of the lowest-ranked term returned — omitted terms fall at or below it.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the description need not repeat safety. It adds valuable behavioral detail: sorting order, counting semantics ('append .exact'), and special handling for identifier fields (bare counting required). It also notes validation rejections (e.g., unbalanced quotes, backslash endings), which are useful edge cases. A small gap is not describing pagination or rate limits, but for a read-only aggregate tool the coverage is strong.

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 information-dense and front-loaded with the core action and output. It earns each sentence, but it is slightly long and the final pairing sentence could be seen as extra. Still, it is well-organized and not padded.

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 a rich schema (100% parameter coverage), a clear output schema, and readOnlyHint annotation, the description fills the gaps that matter: interpretation of results (ranking), use with sibling tools, and critical .exact behavior. An agent has enough to invoke correctly without surprise.

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%, yet the description elevates parameter meaning significantly. It explains when to use .exact, warns that certain fields reject .exact, gives a concrete search example, and clarifies the default/max limit. This goes well beyond the schema's bare descriptions.

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

Purpose5/5

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

Description states a specific verb ('Aggregate and tally'), a resource ('unique values for any field across any openFDA endpoint'), and the output format ('ranked term-count pairs sorted by count descending'). It clearly differentiates from sibling search tools by emphasizing aggregation over retrieval of records.

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

Usage Guidelines5/5

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

Explicitly names six sibling tools as complementary partners for interpreting aggregates ('Pair with...'). It does not spell out when NOT to use this tool, but the pairing guidance strongly implies this tool is for aggregation and those others are for sample records, which is clear directional guidance.

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

openfda_dataframe_describeOpenfda Dataframe DescribeA
Read-onlyIdempotent
Inspect

List the tables and column schemas on a DataCanvas staged by an openFDA search tool. Call before openfda_dataframe_query to discover the exact table name, column names, and DuckDB types needed for valid SQL. row_count is the full staged result set, not the inline preview count. Columns typed JSON hold nested openFDA objects/arrays — query them with DuckDB json functions.

ParametersJSON Schema
NameRequiredDescriptionDefault
canvas_idYesCanvas ID from an openFDA search tool response (present when the search ran with stage=true).

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
tablesNoAll tables and views available on this canvas.
canvas_idNoCanvas ID that was described — pass to openfda_dataframe_query.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds value beyond these by explaining row_count's full-scope meaning and warning that JSON columns hold nested objects needing DuckDB json functions. These are behavioral details not covered by annotations or schema, significantly aiding correct usage.

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 with zero redundancy. The core purpose and usage timing are front-loaded, followed by two essential caveats. Every sentence earns its place, making the description both compact and information-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?

With an output schema present (so return values need no explanation) and annotations covering read-only/idempotent behavior, the description supplies the remaining critical context: call order, row_count semantics, and JSON column handling. Nothing essential is missing for an agent to invoke this tool correctly.

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

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully describes canvas_id (coverage 100%), including its source and the stage=true condition. The description adds no new parameter-specific meaning beyond reinforcing that the canvas comes from an openFDA search tool, which the schema already states. Per the baseline for high coverage, a 3 is appropriate.

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

Purpose5/5

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

The description states a clear verb ('list') and specific resource ('tables and column schemas on a DataCanvas staged by an openFDA search tool'). It differentiates itself from siblings by positioning as a discovery step for the subsequent query tool, making its purpose unambiguous.

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

Usage Guidelines5/5

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

Explicitly instructs to 'Call before openfda_dataframe_query' to discover exact names and types, giving direct when-to-use guidance. It also clarifies row_count semantics ('full staged result set, not inline preview count'), preventing a common misuse. This fully addresses usage context.

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

openfda_dataframe_queryOpenfda Dataframe QueryA
Read-onlyIdempotent
Inspect

Run a read-only SQL SELECT against a DataCanvas table staged by an openFDA search tool (call one with stage=true; its response carries canvas_id + canvas_table). Enables GROUP BY, COUNT/SUM/AVG, time-series, and joins across the staged result set without re-paging the API. Call openfda_dataframe_describe first to get the exact table and column names. Results are capped at the canvas row limit — when truncated is true, page the rest with ORDER BY plus LIMIT/OFFSET. Scalar fields are stored as text (CAST for numeric math); nested objects/arrays are JSON columns — read them with DuckDB json functions, e.g. json_extract_string(openfda, '$.brand_name[0]'). Only SELECT is allowed — DDL, DML, COPY, and file-reading functions are blocked.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesSQL SELECT against the staged table. Use the table name from openfda_dataframe_describe. Example: "SELECT classification, COUNT(*) AS n FROM spilled_ab12cd34 GROUP BY classification ORDER BY n DESC".
canvas_idYesCanvas ID from an openFDA search tool response (the canvas_id field, present when the search ran with stage=true).

Output Schema

ParametersJSON Schema
NameRequiredDescription
rowsNoRows returned by the query (capped at the canvas row limit).
errorNoPresent when the call failed. Absent on success.
canvas_idNoCanvas ID that was queried — reuse for follow-up queries.
row_countNoNumber of rows in this response. Equals the canvas row limit when truncated is true.
truncatedNoTrue when the result hit the canvas row limit and rows beyond it were dropped. Page the rest with ORDER BY plus LIMIT/OFFSET.

TDQS

A4.3/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, and the description is consistent with and enriches them. It discloses the security boundary ('DDL, DML, COPY, and file-reading functions are blocked'), the row-cap behavior with the truncated flag, and crucially the storage semantics ('Scalar fields are stored as text (CAST for numeric math); nested objects/arrays are JSON columns') with a concrete json_extract_string example. This is exactly the behavioral context annotations cannot express, and it contradicts nothing.

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?

A single dense paragraph that front-loads the core purpose before layering preconditions, limits, type semantics, and restrictions. Every sentence carries distinct information (sequencing, truncation paging, CAST, JSON functions, blocked statements) with no filler. Slightly long, but the density is justified for a tool with this much operational nuance.

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

Completeness4/5

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

An output schema exists, so return-value documentation isn't the description's burden. Given the tool's complexity, it covers the essential operational surface: how to reach the right table, how to handle truncation, how to deal with column typing, and the safety boundary. It omits nothing needed to make a correct first call; a worked end-to-end query paired with the describe output is the only optional addition.

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% — both canvas_id and query carry full descriptions with a worked SQL example. The description adds marginal value (the table name comes from openfda_dataframe_describe; canvas_id derives from a stage=true search), which aligns with the schema but does not materially extend it. Baseline 3 is appropriate when the schema already documents both parameters thoroughly.

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: 'Run a read-only SQL SELECT against a DataCanvas table staged by an openFDA search tool'. It clearly distinguishes itself from sibling search tools by explaining it operates on already-staged results rather than paging the API, and it names its companion openfda_dataframe_describe. An agent can tell exactly what this tool does and how it relates to the other openfda_* siblings.

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

Usage Guidelines4/5

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

Explicit sequencing is given: call a search tool with stage=true to obtain canvas_id/canvas_table, and 'Call openfda_dataframe_describe first to get the exact table and column names'. Truncation handling is prescribed ('page the rest with ORDER BY plus LIMIT/OFFSET'). It does not enumerate which sibling tools NOT to use (e.g., openfda_count_values for simple aggregations), so it stops just short of fully routing alternatives, but the preconditions are clear and actionable.

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

openfda_describe_fieldsOpenfda Describe FieldsA
Read-only
Inspect

Return the searchable field paths for an openFDA endpoint, grouped by category with type and description. Use before constructing a search query to find the correct dotted field path — field names differ per endpoint and are not discoverable from the tool schema alone.

ParametersJSON Schema
NameRequiredDescriptionDefault
endpointYesopenFDA endpoint to describe (e.g. "drug/event", "drug/shortages", "device/510k"). Must be one of the cataloged endpoints.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
groupsNoField groups for this endpoint
endpointNoThe endpoint these fields apply to
queryTipsNoopenFDA query syntax reminders relevant to this endpoint

TDQS

A4.1/5.0
Behavior3/5

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

The readOnlyHint annotation already signals this is a safe read operation. The description adds behavioral context beyond that: it returns grouped categories with type and description, and emphasizes that field paths differ across endpoints. This is useful but does not describe the exact output structure; however, an output schema exists, so the return format is already documented. The description supplements annotations adequately.

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

Conciseness5/5

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

The description is two sentences with no filler. The core purpose is front-loaded, followed immediately by the usage context and the rationale for why this tool exists. Every sentence earns its place, and the structure makes it easy for an agent to quickly grasp the tool's role.

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

Completeness5/5

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

For a simple one-parameter discovery tool with an output schema already present, the description is fully complete. It explains what the tool does, when to use it, and why it's necessary, leaving no missing information that an agent would need to make a correct call. The presence of the output schema covers return values, so no further explanation is required.

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

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% coverage for the single 'endpoint' parameter, including an enum of valid values and a description. The tool description adds a rationale for why the endpoint parameter is needed (to identify the correct field paths), but does not provide additional syntax or format details beyond the schema. Given full schema coverage, the baseline score of 3 is appropriate.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Return the searchable field paths for an openFDA endpoint, grouped by category with type and description.' It identifies a specific verb (return), resource (field paths), and the grouping/type/description outcome. This distinguishes it from sibling search/count tools, which operate on data rather than metadata.

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

Usage Guidelines4/5

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

The description provides explicit when-to-use guidance: 'Use before constructing a search query to find the correct dotted field path.' It also explains why (field paths differ per endpoint and are not discoverable from the schema). It does not explicitly name an alternative tool, but the context of 'before constructing a search query' implies the correct timing and alternative search tools. This is clear usage guidance but lacks an explicit exclusion statement.

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

openfda_drug_profileOpenfda Drug ProfileA
Read-only
Inspect

Resolve one drug name to its FDA identity, then fan out in parallel across the bounded per-drug openFDA endpoints and merge into one profile: identity, label highlights, adverse-event summary, recall history, Drugs@FDA approval, and shortage status. Replaces chaining openfda_get_drug_label, openfda_search_adverse_events, openfda_search_recalls, openfda_search_drug_approvals, and openfda_search_drug_shortages — and reconciles the identifier drift between endpoints that makes that chaining error-prone. Each section is best-effort: a miss returns null rather than failing the call. For deep dives into any one area, use the dedicated tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
drugYesDrug name to profile — brand or generic (e.g. "metformin", "Humira", "Glucophage"). Resolved once to canonical FDA identifiers, which then key every sub-query.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoRequest metadata.
errorNoPresent when the call failed. Absent on success.
labelNoLabel highlights from drug/label, or null when no label matched.
noticeNoGuidance when the drug could not be resolved or upstream errors degraded the profile. Absent on a fully populated profile.
recallsNoRecent drug/enforcement recall actions (may be empty).
approvalNoDrugs@FDA approval summary, or null when no application matched.
degradedNoSub-queries that failed upstream, empty when every section resolved. A section listed here is unknown, not absent — a null section with no entry here genuinely has no FDA record.
identityNoIdentity resolved once and reused across every sub-query to avoid identifier drift.
shortageNoCurrent or most-recent drug shortage status, or null when none on record.
sectionsFoundNoHow many profile sections (label, adverse_events, recalls, approval, shortage) returned data.
adverse_eventsNoAdverse-event summary aggregated over drug/event, or null when unavailable.

TDQS

A4.5/5.0
Behavior4/5

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

The annotation already declares readOnlyHint=true, so the safety profile is known. The description adds valuable behavioral context beyond that: fan-out in parallel, merging, best-effort sections that return null on misses, and reconciliation of identifier drift between endpoints. This goes well beyond the annotation, though it does not discuss rate limits or failure modes per sub-query, so not 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?

Four sentences, each earning its place: the core action, the alternatives it replaces, the best-effort note, and routing guidance. The most important content (what it does) is front-loaded. No fluff or repetition of schema or annotation details.

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

Completeness5/5

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

For a complex tool that subsumes five siblings, the description covers purpose, selection criteria, alternative routing, and behavioral expectations. It respects that an output schema exists to document return structure. Nothing an agent needs to decide whether to call it and what to expect 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 parameter's description already explains accepted values (brand or generic) and the resolution behavior. The tool description does not add extra parameter syntax or format details, but the schema carries the load. Baseline 3 is appropriate; there is no gap to penalize or extra value to reward.

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 ('Resolve... then fan out... and merge') and resource (drug profile), and enumerates the concrete sections (identity, label highlights, adverse-event summary, recall history, approval, shortage). It explicitly names the sibling tools it replaces, making it distinct from openfda_get_drug_label, openfda_search_adverse_events, etc. without needing to inspect their schemas.

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

Usage Guidelines5/5

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

It says explicitly when to use this tool (for a combined profile) and when not ('For deep dives into any one area, use the dedicated tool'), and names the exact alternatives. It also flags the rationale (identifier drift) and the best-effort behavior, leaving no ambiguity about selection.

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

openfda_get_drug_labelOpenfda Get Drug LabelA
Read-only
Inspect

Look up FDA drug labeling (package inserts / SPL documents). Check indications, warnings, dosage, contraindications, active ingredients, or any structured label section. A label runs to tens of thousands of tokens, so a page that exceeds the inline budget returns the list of available sections instead; re-call with sections to pull the ones you need.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: effective_time:desc. Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. A well-formed but non-sortable field still causes a query error — use a documented field name.
limitNoMaximum number of results to return (1-1000). Default 5. Labels are large, and the cost of a sections selection is the section summed across every record on the page — so it scales with this limit. Lower it before widening a selection.
searchYesQuery targeting label fields. Examples: openfda.brand_name:"aspirin", openfda.generic_name:"metformin", openfda.manufacturer_name:"pfizer". For a specific revision, pass set_id with the SPL UUID returned in earlier results. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
sectionsNoLabel sections to return, e.g. ["boxed_warning","indications_and_usage"]. Names come from the outline an oversized page returns, or from openfda_describe_fields. Omit for the whole label — which returns the section outline instead when the page exceeds the inline size budget. A selection is returned whole even when it exceeds that budget, with its serialized size reported on the notice; the outline names a section measured to fit at the requested limit. Metadata (openfda, set_id, id, effective_time, version) is returned either way and counts toward the size.

Output Schema

ParametersJSON Schema
NameRequiredDescription
capNoThe limit applied to this page.
kindNoWhether this response carries label records ("full") or only the section outline of a page too large to inline ("outline").
metaNoPagination and freshness metadata.
errorNoPresent when the call failed. Absent on success.
shownNoNumber of labels returned in this response.
noticeNoGuidance for this page: how to broaden filters or correct field names when results are empty or paging overshot, the sized re-call example when a page overflowed to its section outline, section names no record carried, and the serialized size when a sections selection exceeds the inline budget. Absent when nothing needs saying.
outlineNoSection names available across the matched page and their serialized size, largest first. Present when kind is "outline" — pass names back in sections to retrieve them.
resultsNoDrug label records, present when kind is "full". Each carries an openfda block (brand_name, generic_name, manufacturer_name, route) plus optional SPL sections like indications_and_usage, warnings, dosage_and_administration, contraindications, adverse_reactions; section presence varies per label. Narrowed to the requested sections plus metadata when sections was supplied.
truncatedNoTrue when more labels matched than this page returned — page with skip for the rest.
totalResultsNoTotal matching label records in the dataset
effectiveQueryNoSearch filter applied to the drug label query, as submitted to openFDA

TDQS

A4.2/5.0
Behavior4/5

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

The readOnlyHint annotation already covers the read-only nature, so the description appropriately focuses on extra behavioral details: the token-size budget, the fallback to a section outline, and the need to re-call with specific sections. This adds genuine value beyond the annotation and does not contradict it.

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

Conciseness5/5

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

The description is compact and front-loaded with the primary purpose, then explains the important behavioral nuance in a single follow-up sentence. There is no filler or redundancy; every clause earns its place.

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

Completeness4/5

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

For a tool with 5 parameters and an output schema, the description covers the critical behavioral aspect—how large pages are handled and the sections mechanism—and mentions metadata inclusion indirectly via 'any structured label section.' The schema fills in parameter details, so the description is sufficient for an agent to understand what to expect, though it could briefly note the response structure beyond what the schema provides.

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 each parameter has a detailed description (e.g., search examples, sort pattern, limit scaling). The description adds only a minor hint about the 'sections' parameter through the re-call guidance, but nothing that substantially enhances understanding beyond the schema. Baseline 3 is appropriate.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Look up FDA drug labeling' with specific examples of label sections (indications, warnings, dosage, etc.). It is immediately distinct from sibling tools that search for adverse events, recalls, or approvals, and the verb 'look up' matches the read-only intent.

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

Usage Guidelines4/5

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

The description implies when to use it (any time label content is needed) and provides a clear usage pattern for oversized pages: 're-call with sections to pull the ones you need.' It does not explicitly name alternatives or exclusions, but the domain is well defined and the fallback behavior is explained, giving an agent enough context to decide when this tool applies.

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

openfda_lookup_ndcOpenfda Lookup NdcA
Read-only
Inspect

Look up drugs in the NDC (National Drug Code) Directory. Identify drug products by NDC code, find active ingredients, packaging details, or manufacturer info. Pair with openfda_get_drug_label using the returned brand_name or set_id to read the package insert.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: listing_expiration_date:desc. Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. A well-formed but non-sortable field still causes a query error — use a documented field name.
limitNoMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized budget: a page that would overrun it returns fewer records than requested and reports the cut on page_omitted. Whenever any record matched, at least one comes back, however large it measures. A record grows with its packaging list, so a product with many package configurations is several times the size of one with a single package.
stageNoStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a canvas table up to a size budget (staged_rows reports how many reached it). Staging is for record-level SQL over a bounded slice; for a distribution over everything that matched, openfda_count_values aggregates server-side in one request. Requires CANVAS_PROVIDER_TYPE=duckdb.
searchYesopenFDA search query. Examples: product_ndc:"0363-0218", brand_name:"aspirin", generic_name:"metformin", openfda.manufacturer_name:"walgreen", active_ingredients.name:"ASPIRIN". Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
canvas_idNoDataCanvas session id from a prior call. Passing one stages this lookup onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
noticeNoCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broaden filters or correct field names.
resultsNoNDC directory records — product_ndc, brand_name, generic_name, labeler_name, dosage_form, route, marketing_category, active_ingredients[], packaging[], listing_expiration_date.
spilledNoTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
canvas_idNoDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the same canvas.
truncatedNoTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.
page_bytesNoSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
staged_rowsNoRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
canvas_tableNoCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
page_omittedNoRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of records returned, lower limit for a smaller page, or pass stage=true to query a bounded drain of the match with openfda_dataframe_query.
totalResultsNoTotal matching NDC records in the dataset
effectiveQueryNoSearch filter applied to the NDC lookup, as submitted to openFDA

TDQS

A4.1/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds a useful integration hint (pairing with get_drug_label) and mentions output fields, but does not disclose additional behavioral traits beyond what annotations and the schema (pagination, limits) already describe. A 3 is the appropriate baseline.

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 with no wasted words: first states the core purpose, second lists searchable attributes, third gives a practical integration hint. The key 'look up drugs in NDC Directory' is front-loaded, making it instantly scannable.

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

Completeness5/5

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

Given the rich schema (all parameters documented) and an output schema, the description provides all necessary high-level context, including a pointer to a related tool for further steps. Pagination, sort, and other details are covered schematically, so nothing essential is omitted.

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 all six parameters have detailed descriptions. The description adds no extra parameter-level meaning; only mentions output fields (brand_name, set_id) which is fine. 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?

The description clearly states the tool looks up drugs in the NDC Directory and enumerates the specific identifiers it can find (NDC code, active ingredients, packaging, manufacturer). This differentiates it from siblings like openfda_search_adverse_events or openfda_get_drug_label without needing to inspect schemas.

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 provides a concrete use case (identify drug products) and explicitly suggests pairing with openfda_get_drug_label using returned fields, which is actionable. However, it does not explicitly mention when not to use this tool or contrast with similar options like openfda_drug_profile, so it misses the full 'when-not/alternatives' guidance.

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

openfda_search_adverse_eventsOpenfda Search Adverse EventsA
Read-only
Inspect

Search adverse event reports across drugs, food, and devices. Use to investigate safety signals, find reports for a specific product, or explore reactions by demographics.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. Sortable date fields are category-specific: drug → receivedate:desc (or receiptdate), food → date_created:desc (or date_started), device → date_received:desc (or date_of_event). A field from another category (e.g. receivedate on food or device) causes a query error — use the field for this category.
limitNoMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized budget: a page that would overrun it returns fewer records than requested and reports the cut on page_omitted. Whenever any record matched, at least one comes back, however large it measures. Drug reports are by far the largest — a single drug/event report averages tens of kilobytes where a food/event report is a few hundred bytes.
stageNoStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a canvas table up to a size budget (staged_rows reports how many reached it). Staging is for record-level SQL over a bounded slice; for a distribution over everything that matched, openfda_count_values aggregates server-side in one request. Requires CANVAS_PROVIDER_TYPE=duckdb.
searchNoopenFDA search query. Examples: patient.drug.medicinalproduct:"aspirin", patient.reaction.reactionmeddrapt:"nausea" AND serious:"1". Omit to browse recent. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
categoryYesProduct category — each has different field schemas in the response
canvas_idNoDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
noticeNoCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty or paging overshot — how to broaden filters or adjust the query.
resultsNoAdverse event records — fields vary by category (drug: patient/reactions/drugs, device: device details/event type, food: products/outcomes)
spilledNoTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
canvas_idNoDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the same canvas.
truncatedNoTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.
page_bytesNoSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
staged_rowsNoRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
canvas_tableNoCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
page_omittedNoRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of records returned, lower limit for a smaller page, or pass stage=true to query a bounded drain of the match with openfda_dataframe_query.
totalResultsNoTotal matching adverse event records in the dataset
effectiveQueryNoSearch filter applied to the query, as submitted to openFDA

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, so the description does not need to state that this is a read operation. The description adds no behavioral detail beyond purpose; however, the input schema carries extensive behavioral notes (pagination limits, category-specific sort fields, staging behavior, byte budgets). Since annotations reduce the burden and the schema covers operational caveats, a score of 3 is appropriate rather than lower.

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

Conciseness5/5

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

Two sentences with no filler: the first clearly states the verb and resource, the second enumerates three concrete use cases. Every word earns its place, and the core purpose is front-loaded.

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

Completeness4/5

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

For a tool with 7 parameters and a rich output schema, the description gives enough context for an agent to understand what the tool does and when to use it. It does not reference the operational complexities (pagination limits, category-specific sorting, staging), but those are fully documented in the schema. The description is complete for decision-making, though not exhaustive.

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 provides thorough explanations for every parameter (skip pagination cap, sort field limitations, limit byte budget, search syntax constraints, category enum, staging semantics). The description itself adds no parameter-level meaning beyond what the schema already provides, matching the baseline for high coverage.

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

Purpose5/5

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

The description states a specific verb ('Search') and a precise resource ('adverse event reports across drugs, food, and devices'), and gives concrete use cases (investigate safety signals, find reports for a product, explore demographics). This clearly distinguishes it from sibling search tools for recalls, approvals, and animal events, even though no sibling is named.

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

Usage Guidelines4/5

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

The description provides explicit use cases ('investigate safety signals, find reports for a specific product, or explore reactions by demographics'), which implicitly tells the agent when to reach for this tool. It does not name alternatives or state exclusions, but given the domain-specific nature of the tool and the sibling set, the context is sufficient to guide selection.

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

openfda_search_animal_eventsOpenfda Search Animal EventsA
Read-only
Inspect

Search adverse event reports for veterinary drugs and devices submitted to the FDA Center for Veterinary Medicine. Records include animal species, breed, age, weight, drug name and route, adverse reactions (using VeDDRA terminology), and outcome. Use to investigate safety signals for veterinary products, find reports by animal species or drug, or explore reaction patterns.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: original_receive_date:desc. Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. A well-formed but non-sortable field still causes a query error — use a documented field name.
limitNoMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized budget: a page that would overrun it returns fewer records than requested and reports the cut on page_omitted. Whenever any record matched, at least one comes back, however large it measures.
stageNoStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a canvas table up to a size budget (staged_rows reports how many reached it). Staging is for record-level SQL over a bounded slice; for a distribution over everything that matched, openfda_count_values aggregates server-side in one request. Requires CANVAS_PROVIDER_TYPE=duckdb.
searchNoopenFDA search query using field:value syntax. Examples: animal.species:"Dog", drug.brand_name:"Bravecto", reaction.veddra_term_name:"Vomiting", serious_ae:"true". Omit to browse recent reports. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
canvas_idNoDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
noticeNoCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty or paging overshot — how to broaden filters or adjust the query.
resultsNoAnimal adverse event records. Key fields: unique_aer_id_number, original_receive_date, serious_ae, animal (species, gender, breed, age, weight), drug[] (brand_name, active_ingredients, route, dose, administered_by), reaction[] (veddra_term_name, number_of_animals_affected), outcome[] (medical_status), primary_reporter, type_of_information.
spilledNoTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
canvas_idNoDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the same canvas.
truncatedNoTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.
page_bytesNoSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
staged_rowsNoRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
canvas_tableNoCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
page_omittedNoRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of records returned, lower limit for a smaller page, or pass stage=true to query a bounded drain of the match with openfda_dataframe_query.
totalResultsNoTotal matching animal adverse event records in the dataset
effectiveQueryNoSearch filter applied to the query, as submitted to openFDA

TDQS

A4/5.0
Behavior3/5

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

Annotations declare readOnlyHint=true, so the read-only nature is already covered. The description adds context about the data fields (species, breed, age, reactions, outcome) but does not disclose pagination limits, staging behavior, or response format—these are handled in the schema. It neither contradicts annotations nor adds significant behavioral nuance beyond the safety hint, so baseline 3 is appropriate.

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

Conciseness5/5

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

The description is two sentences with no filler. The first sentence states purpose and data content, the second gives use cases. Everything earns its place and is front-loaded, making it easy for an agent to quickly grasp the tool's function.

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

Completeness4/5

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

Given the detailed input schema (100% coverage) and an output schema, the description is sufficiently complete for correct invocation. It covers domain, data elements, and typical use cases. It doesn't repeat schema details, which is appropriate, though it omits nuanced behaviors like staging or pagination limits that are already documented in the schema.

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

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter has a detailed description covering syntax, defaults, and edge cases (e.g., pagination limit, serialized size budget, staging semantics). The tool description adds minimal parameter-specific meaning, only implying the searchable fields. Baseline 3 is suitable because the schema already carries the full semantic load.

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 (search) and resource (adverse event reports for veterinary drugs and devices) and explicitly scopes to the FDA Center for Veterinary Medicine. It lists the record contents and distinguishes from the sibling openfda_search_adverse_events by specifying the veterinary focus, so an agent can tell them apart 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 Guidelines4/5

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

The description provides clear usage context: 'investigate safety signals for veterinary products, find reports by animal species or drug, or explore reaction patterns.' It does not explicitly mention when not to use it or name alternative tools, but the purpose and data scope make the intended use obvious. Lacks explicit exclusions but gives appropriate situational guidance.

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

openfda_search_device_clearancesOpenfda Search Device ClearancesB
Read-only
Inspect

Search FDA device premarket notifications — 510(k) clearances and PMA approvals.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: decision_date:desc. Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. A well-formed but non-sortable field still causes a query error — use a documented field name.
limitNoMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized budget: a page that would overrun it returns fewer records than requested and reports the cut on page_omitted. Whenever any record matched, at least one comes back, however large it measures. A 510(k) record carries a summary narrative and is several times the size of a PMA record.
stageNoStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a canvas table up to a size budget (staged_rows reports how many reached it). Staging is for record-level SQL over a bounded slice; for a distribution over everything that matched, openfda_count_values aggregates server-side in one request. Requires CANVAS_PROVIDER_TYPE=duckdb.
searchNoopenFDA search query. Examples: applicant:"medtronic", advisory_committee_description:"cardiovascular", product_code:"DXN", openfda.device_name:"catheter". Omit to browse recent. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
pathwayYesPremarket pathway. 510(k) is the most common; PMA is for higher-risk devices.
canvas_idNoDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
noticeNoCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broaden filters or correct field names.
resultsNo510(k) or PMA records — 510(k) carries k_number, device_name, applicant, product_code, decision_date, decision_description, advisory_committee_description; PMA carries pma_number, trade_name, generic_name, supplement_number plus shared applicant/product_code/decision_date/decision_description.
spilledNoTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
canvas_idNoDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the same canvas.
truncatedNoTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.
page_bytesNoSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
staged_rowsNoRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
canvas_tableNoCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
page_omittedNoRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of records returned, lower limit for a smaller page, or pass stage=true to query a bounded drain of the match with openfda_dataframe_query.
totalResultsNoTotal matching device clearance records in the dataset
effectiveQueryNoSearch filter applied to the device clearance query, as submitted to openFDA

TDQS

B3.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, so the description need not repeat that. The description adds no additional behavioral context (e.g., pagination limits, large-record implications, or error behavior). However, it does not contradict the annotation, and given the readOnlyHint coverage, a baseline score is appropriate.

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

Conciseness5/5

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

A single, front-loaded sentence that states exactly what the tool does with no filler. Every word earns its place; it is appropriately sized for a search tool.

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

Completeness3/5

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

For a 7-parameter tool with an output schema and rich schema descriptions, the description is minimal but the schema covers parameter semantics and the output schema covers return structure. The main gap is the lack of usage guidance and behavioral context (e.g., mention that 510(k) records are larger than PMA records, which the schema does note). Overall, the description is adequate but not complete on its own.

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

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with all seven parameters documented in the schema (including detailed notes on each). The description itself contributes zero parameter-level meaning. Baseline 3 is fair because the schema fully carries the parameter semantics.

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

Purpose4/5

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

The description states a specific verb ('Search') and a resource ('FDA device premarket notifications') with explicit subtypes ('510(k) clearances and PMA approvals'). It clearly distinguishes from drug-related search tools like openfda_search_drug_approvals, but does not reference any sibling by name, so the differentiation is implicit rather than explicit.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It does not mention categories like 'use for device clearance documents' or contrast with drug-related searches. The sibling names exist (e.g., openfda_search_drug_approvals) but are not referenced, leaving selection entirely to the agent's inference from the resource name.

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

openfda_search_drug_approvalsOpenfda Search Drug ApprovalsA
Read-only
Inspect

Search the Drugs@FDA database for drug application approvals (NDAs and ANDAs). Returns application details, sponsor info, and full submission history. Pair with openfda_get_drug_label to read the approved label, or openfda_count_values to aggregate by sponsor_name, product_type, or route.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: submissions.submission_status_date:desc. Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. A well-formed but non-sortable field still causes a query error — use a documented field name.
limitNoMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized budget: a page that would overrun it returns fewer records than requested and reports the cut on page_omitted. Whenever any record matched, at least one comes back, however large it measures. A record carries its application's whole submission history, so a long-running application is an order of magnitude larger than a recent one.
stageNoStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a canvas table up to a size budget (staged_rows reports how many reached it). Staging is for record-level SQL over a bounded slice; for a distribution over everything that matched, openfda_count_values aggregates server-side in one request. Requires CANVAS_PROVIDER_TYPE=duckdb.
searchNoopenFDA search query. Examples: openfda.brand_name:"humira", sponsor_name:"PFIZER", submissions.submission_type:"ORIG" AND submissions.review_priority:"PRIORITY". Exact quoted values can be case-sensitive on some fields — sponsor_name is stored uppercase, so use sponsor_name:"PFIZER" (a lowercase quoted value returns no matches). Omit to browse recent. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
canvas_idNoDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
noticeNoCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broaden filters or correct field names.
resultsNoDrug application records — application_number, sponsor_name, openfda block (brand_name, generic_name, route, product_type, substance_name), products[] (active_ingredients, dosage_form, marketing_status), submissions[] (submission_type, submission_status, submission_status_date, review_priority).
spilledNoTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
canvas_idNoDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the same canvas.
truncatedNoTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.
page_bytesNoSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
staged_rowsNoRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
canvas_tableNoCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
page_omittedNoRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of records returned, lower limit for a smaller page, or pass stage=true to query a bounded drain of the match with openfda_dataframe_query.
totalResultsNoTotal matching drug approval records in the dataset
effectiveQueryNoSearch filter applied to the Drugs@FDA query, as submitted to openFDA

TDQS

A4.1/5.0
Behavior3/5

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

The annotation readOnlyHint=true already conveys the read-only nature, lowering the burden on the description. The description adds that it returns 'application details, sponsor info, and full submission history', which is marginally beyond the annotation but not deeply behavioral (e.g., pagination, errors are left to the schema). No contradictions with annotations found.

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 exactly two sentences: the first front-loads the core purpose, and the second provides concise pairing guidance. Every phrase adds value; no redundancy or filler 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?

Given an output schema exists and the parameter schema fully documents all 6 optional parameters, the description covers the essential usage context. It explains where the data comes from, what it returns, and how to extend the workflow with complementary tools. Nothing critical for an agent to call the tool correctly is missing.

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

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage with detailed descriptions for each of the 6 parameters, including pagination limits, sort syntax, staging behavior, and search examples. The description does not need to add parameter-level detail, so a baseline score of 3 is appropriate. It even hints at aggregatable fields (sponsor_name, product_type, route) which complements the schema.

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

Purpose5/5

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

The description states a specific verb ('Search'), resource ('Drugs@FDA database'), and scope ('drug application approvals (NDAs and ANDAs)'), making the tool's purpose unambiguous. It also distinguishes from siblings like openfda_search_adverse_events by focusing on approvals, and mentions the return content (application details, sponsor info, submission history).

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

Usage Guidelines4/5

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

The description explicitly recommends pairing with openfda_get_drug_label to read approved labels and openfda_count_values for aggregation, providing clear workflow guidance. It implies when to use this tool versus alternatives by naming the database and approval focus, though it does not explicitly exclude other search tools. The purpose is distinct enough that an agent can infer when to choose this tool.

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

openfda_search_drug_shortagesOpenfda Search Drug ShortagesA
Read-only
Inspect

Search FDA drug shortage records. Returns per-product shortage status, availability, therapeutic category, dosage form, manufacturer, and dates. Use to check whether a drug is currently in shortage, find all oncology drugs with supply issues, or retrieve the openfda block (brand_name, product_ndc, rxcui) to chain into openfda_get_drug_label or openfda_lookup_ndc.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: update_date:desc. Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. A well-formed but non-sortable field still causes a query error — use a documented field name.
limitNoMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized budget: a page that would overrun it returns fewer records than requested and reports the cut on page_omitted. Whenever any record matched, at least one comes back, however large it measures.
stageNoStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a canvas table up to a size budget (staged_rows reports how many reached it). Staging is for record-level SQL over a bounded slice; for a distribution over everything that matched, openfda_count_values aggregates server-side in one request. Requires CANVAS_PROVIDER_TYPE=duckdb.
searchNoopenFDA search query using field:value syntax. Examples: status:"Current", therapeutic_category:"Oncology", generic_name:"carboplatin", company_name:"pfizer". Omit to browse all records. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request. Call openfda_describe_fields({ endpoint: "drug/shortages" }) for the complete field list.
canvas_idNoDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
noticeNoCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broaden filters or correct field names.
resultsNoDrug shortage records. Key fields: generic_name, status ("Current"/"Resolved"), availability, therapeutic_category, dosage_form, presentation, package_ndc, company_name, contact_info, initial_posting_date, update_date, update_type. openfda block contains brand_name, product_ndc, rxcui, spl_set_id for cross-linking.
spilledNoTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
canvas_idNoDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the same canvas.
truncatedNoTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.
page_bytesNoSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
staged_rowsNoRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
canvas_tableNoCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
page_omittedNoRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of records returned, lower limit for a smaller page, or pass stage=true to query a bounded drain of the match with openfda_dataframe_query.
totalResultsNoTotal matching drug shortage records in the dataset
effectiveQueryNoSearch filter applied to the drug/shortages query, as submitted to openFDA

TDQS

A4.3/5.0
Behavior4/5

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

Annotations carry readOnlyHint=true, lowering the safety burden. The description goes beyond this by disclosing exactly what is returned and the chaining behavior for the openfda block. Parameter descriptions add further behavioral context (pagination caps, staged_row cutoffs, sort rejection). No contradiction with annotations.

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

Conciseness5/5

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

Three front-loaded sentences with zero waste: purpose and returned fields first, then use cases, then chaining targets. Every sentence earns its place and the most decision-relevant info (what it does, what it returns) leads.

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

Completeness5/5

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

With an output schema present, return values need no explanation in the description. Zero required parameters, all 6 params fully documented in the schema, and the description covers purpose, use cases, and cross-tool chaining. Nothing an agent needs to call it correctly is missing.

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

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with detailed descriptions on all 6 parameters (pagination bounds, sort syntax, stage budget, search field examples, canvas_id semantics). Baseline 3 applies; the description itself adds no parameter details beyond what the schema already provides.

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+resource ("Search FDA drug shortage records") and enumerates the returned fields (status, availability, therapeutic category, dosage form, manufacturer, dates). It clearly differentiates from sibling search tools by scoping to the drug/shortages endpoint and names the two chaining targets (openfda_get_drug_label, openfda_lookup_ndc).

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 lists concrete use cases: checking current shortage status, finding oncology drugs with supply issues, and retrieving the openfda block for chaining. The stage parameter additionally routes to openfda_count_values and openfda_dataframe_query as alternatives. It lacks an explicit when-NOT-to-use statement, but given the sibling set is all distinct endpoints, the guidance is sufficient.

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

openfda_search_recallsOpenfda Search RecallsC
Read-only
Inspect

Search enforcement reports and recall actions across drugs, food, and devices.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort (e.g. report_date:desc,status.exact:asc). Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. A well-formed but non-sortable field still causes a query error — use a documented field name.
limitNoMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized budget: a page that would overrun it returns fewer records than requested and reports the cut on page_omitted. Whenever any record matched, at least one comes back, however large it measures. Device records are the largest here — a device enforcement or recall record runs several kilobytes where a drug or food enforcement record is around one.
stageNoStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a canvas table up to a size budget (staged_rows reports how many reached it). Staging is for record-level SQL over a bounded slice; for a distribution over everything that matched, openfda_count_values aggregates server-side in one request. Requires CANVAS_PROVIDER_TYPE=duckdb.
searchNoopenFDA search query. Examples: classification:"Class I" (also "Class II" or "Class III"), recalling_firm:"pfizer", reason_for_recall:"undeclared allergen". Omit to browse recent. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
categoryYesProduct category
endpointNoReport type. Default enforcement. The recall endpoint is only available for devices.enforcement
canvas_idNoDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
noticeNoCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broaden filters or correct field names.
resultsNoEnforcement or recall records — recall_number, classification, recalling_firm, product_description, reason_for_recall, status, voluntary_mandated, distribution_pattern, report_date. Field set varies between enforcement and recall endpoints.
spilledNoTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
canvas_idNoDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the same canvas.
truncatedNoTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.
page_bytesNoSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
staged_rowsNoRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
canvas_tableNoCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
page_omittedNoRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of records returned, lower limit for a smaller page, or pass stage=true to query a bounded drain of the match with openfda_dataframe_query.
totalResultsNoTotal matching recall/enforcement records in the dataset
effectiveQueryNoSearch filter applied to the recall query, as submitted to openFDA

TDQS

C2.9/5.0
Behavior2/5

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

The only annotation is readOnlyHint=true, which is consistent with the 'Search' action, but the description adds no behavioral context beyond that. It does not mention pagination limits, result size budgets, staging behavior, or any other operational traits. The schema descriptions cover some behaviors (e.g., pagination cap, size budget), but the tool description itself is silent, so the agent must read the schema to learn these details.

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

Conciseness4/5

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

The description is a single, compact sentence that front-loads the purpose and includes the key categories. It is concise with no filler. However, it is so brief that it omits contextual guidance that would be useful for an 8-parameter tool, which slightly reduces its structural value despite its efficiency.

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

Completeness2/5

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

Given the tool's complexity (8 parameters, two endpoints, three categories, an output schema), a single-sentence description is insufficient. It does not explain the difference between the 'enforcement' and 'recall' endpoints, when to use one over the other, or any high-level usage nuances. The schema carries this weight, but the description fails to summarize key decisions or point the agent to relevant alternatives, leaving the agent to dive into the schema without guidance.

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

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool description contains no parameter information, but the schema provides 100% coverage with detailed descriptions for all 8 parameters, including defaults, constraints, examples, and behavioral notes (e.g., pagination cap, size budget for limit, staging behavior for stage/canvas_id). The description adds no meaning beyond what the schema already provides, so it meets the baseline for high schema coverage.

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

Purpose4/5

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

The description states a clear verb ('Search') and a specific resource ('enforcement reports and recall actions') across three categories (drugs, food, devices). It is unambiguous about the subject matter, though it does not explicitly differentiate from sibling search tools like openfda_search_adverse_events or openfda_search_device_clearances. The name itself is specific enough that an agent can infer its scope.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It does not mention exclusions, alternative tools, or any decision criteria. The parameter schema includes a note about staging vs. openfda_count_values, but that is buried in parameter descriptions and not surfaced in the tool description itself. An agent cannot tell from the description when to choose this over another search tool.

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

openfda_search_tobacco_reportsOpenfda Search Tobacco ReportsA
Read-only
Inspect

Search problem reports submitted to the FDA for tobacco products, including e-cigarettes, vaping products, cigarettes, and smokeless tobacco. Reports capture product type, reported health problems (e.g. seizure, chest pain), product problems (e.g. exploding battery), whether a non-user was affected, and submission date. Use to investigate safety signals, find reports by product type, or analyze health effects.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortNoSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: date_submitted:desc. Field paths take only letters, digits, underscores, and dots; anything else is rejected before the request. A well-formed but non-sortable field still causes a query error — use a documented field name.
limitNoMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized budget: a page that would overrun it returns fewer records than requested and reports the cut on page_omitted. Whenever any record matched, at least one comes back, however large it measures.
stageNoStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a canvas table up to a size budget (staged_rows reports how many reached it). Staging is for record-level SQL over a bounded slice; for a distribution over everything that matched, openfda_count_values aggregates server-side in one request. Requires CANVAS_PROVIDER_TYPE=duckdb.
searchNoopenFDA search query using field:value syntax. Examples: tobacco_products:"Electronic cigarette", reported_health_problems:"Seizure", nonuser_affected:"Yes". Omit to browse recent reports. Double quotes, parentheses, and range brackets must balance, and the query must not end on a backslash — each is rejected before the request.
canvas_idNoDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNoResponse metadata
errorNoPresent when the call failed. Absent on success.
noticeNoCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty or paging overshot — how to broaden filters or adjust the query.
resultsNoTobacco problem report records. Key fields: report_id, date_submitted, tobacco_products[] (product type description), reported_health_problems[] (health effects), reported_product_problems[] (device/product defects), number_tobacco_products, number_health_problems, number_product_problems, nonuser_affected.
spilledNoTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
canvas_idNoDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the same canvas.
truncatedNoTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.
page_bytesNoSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
staged_rowsNoRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
canvas_tableNoCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
page_omittedNoRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of records returned, lower limit for a smaller page, or pass stage=true to query a bounded drain of the match with openfda_dataframe_query.
totalResultsNoTotal matching tobacco problem reports in the dataset
effectiveQueryNoSearch filter applied to the query, as submitted to openFDA

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, and the description does not contradict that. The description adds minimal behavioral context beyond what annotations provide – it mentions the types of data captured but does not disclose pagination limits, error behaviors, or any side effects. Since annotations cover the safety profile, the description's extra information is useful but not extensive.

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

Conciseness4/5

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

The description is a single, reasonably concise paragraph of three sentences that front-loads the core purpose and follows with examples of report content and use cases. It contains no filler or repetition, though it could be slightly tightened by moving some detail into the schema, but it remains efficient and well-structured.

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

Completeness4/5

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

The description is complete enough for an agent to select and call the tool: it covers what the tool does, what data it returns, and common use cases. Output schema is present, so return details are covered there. It does not explicitly mention error conditions or rate limits, but those are documented in parameter descriptions. For a search tool with no required parameters and clear annotations, the contextual information is sufficient.

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

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with all six parameters (skip, sort, limit, stage, search, canvas_id) having detailed descriptions including examples and constraints. The tool description repeats some example search fields (e.g., reported_health_problems) that also appear in the schema, adding minimal new meaning. It does not compensate for any parameter gaps because there are none, 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?

The description states a specific verb ('Search') and resource ('problem reports submitted to the FDA for tobacco products'), and enumerates the content of those reports (product type, health problems, product problems, etc.). It clearly differentiates from sibling search tools like openfda_search_adverse_events by explicitly scoping to tobacco products, making it unambiguous what this tool is for.

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 use cases ('investigate safety signals, find reports by product type, or analyze health effects') that indicate when the tool is appropriate. It does not explicitly name alternatives or state when not to use it, but the domain-specific language implicitly distinguishes it from other product-type search tools. This is clear context without explicit exclusions.

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

Frequently Asked Questions

Discussions

No comments yet. Be the first to start the discussion!

Related MCP Connectors

Related MCP Servers

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4/5.0
Disambiguation5/5

Each tool targets a distinct FDA endpoint or analytic function. Search tools are separated by domain (adverse events, animal events, recalls, tobacco, etc.), and utility tools (count_values, describe_fields, dataframe_describe/query, drug_profile) serve unique purposes without overlap. An agent can clearly identify which tool to call for a given task.

Naming Consistency5/5

All tools follow a consistent openfda_<action>_<object> pattern in snake_case. Search tools use search_<domain>, while utility tools use clear verbs like get, lookup, count, describe, and query. The only slight deviation is drug_profile (a noun phrase), but it remains intuitive and fits the naming style.

Tool Count5/5

With 14 tools, the server is well-scoped for its purpose of providing access to multiple openFDA endpoints. Each tool covers a distinct resource or analytic capability, and none feel redundant. The count sits comfortably within the ideal range for a domain-specific server.

Completeness5/5

The server covers the major openFDA data categories: adverse events (human/animal), device clearances, drug approvals, shortages, recalls, tobacco, labels, and NDC lookup. It also provides robust analytics via count_values and dataframe queries, plus field discovery. There are no obvious gaps for the stated domain, and the composite drug_profile fills integration needs.