openfda-mcp-server
Server Details
Query FDA data on drugs, food, devices, and recalls via openFDA. STDIO or Streamable HTTP.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- cyanheads/openfda-mcp-server
- GitHub Stars
- 4
- Server Listing
- @cyanheads/openfda-mcp-server
Glama MCP Gateway
Connect through Glama MCP Gateway for full control over tool access and complete visibility into every call.
Full call logging
Every tool call is logged with complete inputs and outputs, so you can debug issues and audit what your agents are doing.
Tool access control
Enable or disable individual tools per connector, so you decide what your agents can and cannot do.
Managed credentials
Glama handles OAuth flows, token storage, and automatic rotation, so credentials never expire on your clients.
Usage analytics
See which tools your agents call, how often, and when, so you can understand usage patterns and catch anomalies.
Tool Definition Quality
Average 4.2/5 across 14 of 14 tools scored. Lowest: 3.3/5.
Each tool targets a distinct FDA data domain or utility (e.g., adverse events, drug approvals, recalls, DataFrame operations). Descriptions are explicit about differences, such as separating animal events from human events, and the drug profile tool clearly replaces chaining multiple tools.
Tools follow a consistent 'openfda_' prefix with a verb-noun pattern (e.g., search_adverse_events, get_drug_label). Minor deviations like 'drug_profile' (noun-verb) and 'describe_fields' vs 'dataframe_describe' slightly break the pattern but remain understandable.
14 tools cover a broad range of FDA data sources (drugs, devices, food, tobacco, recalls, shortages) and include analytical helpers (count_values, DataFrame tools). The count is well-scoped for the domain—neither too sparse nor excessive.
The set covers major openFDA endpoints: adverse events, drug approvals, recalls, device clearances, labeling, NDC, shortages, and animal/tobacco reports. Missing endpoints like food contamination or cosmetics are niche, so the coverage is strong for common use cases.
Available Tools
14 toolsopenfda_count_valuesOpenfda Count ValuesARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| count | Yes | Field 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. | |
| limit | No | Number of top terms to return (default 100, max 1000) | |
| search | No | Filter 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. | |
| endpoint | Yes | Full openFDA endpoint path (e.g. "drug/event", "device/classification") |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The limit applied to the term list. |
| meta | Yes | Response metadata |
| shown | No | Number of terms returned in this response. |
| notice | No | Guidance when no terms matched — how to verify the field name or adjust the count expression. Absent when terms are returned. |
| results | Yes | Term-count pairs sorted by count descending |
| termCount | Yes | Number of distinct terms returned |
| truncated | No | True when the term list was capped at the limit — more distinct terms may exist. |
| truncationCeiling | No | Count of the lowest-ranked term returned — omitted terms fall at or below it. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, so no safety contradiction. The description adds valuable behavioral detail: returns ranked term-count pairs sorted by count descending. It doesn't mention rate limits or edge cases, but the annotation lowers the bar.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose, and no wasted words. The pairing guidance is placed effectively without diluting the primary function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the schema covers all parameters and an output schema exists, the description is complete. It explains the return format, general scope, and complementary tools, making it fully contextual for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are fully documented. The description adds no extra parameter semantics beyond what the schema already provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Aggregate and tally unique values' and the resource 'any field across any openFDA endpoint'. It distinguishes this tool from siblings like openfda_describe_fields or search tools by focusing on aggregation and ranked counting.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear usage context by suggesting pairing with specific search tools when sample records help interpret aggregates. However, it does not explicitly state when not to use this tool or compare it with dataframe_query/describe fields.
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 DescribeARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| canvas_id | Yes | Canvas ID from an openFDA search tool response (present when the search ran with stage=true). |
Output Schema
| Name | Required | Description |
|---|---|---|
| tables | Yes | All tables and views available on this canvas. |
| canvas_id | Yes | Canvas ID that was described — pass to openfda_dataframe_query. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint and idempotentHint, so safety is covered. The description goes further by explaining key behaviors: row_count reflects the full staged result set (not preview count), and JSON columns require DuckDB json functions. This adds actionable context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with the primary purpose front-loaded. Subsequent sentences provide essential usage context and data behavior notes. No redundant or filler content; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and strong annotations, the description covers all needed context: purpose, usage relationship to query tool, row_count semantics, and JSON query tips. This is complete for a metadata-discovery tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% because the single canvas_id parameter is fully described with its source and condition. The description reinforces that canvas_id comes from a staged search, but adds no new semantic detail beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List the tables and column schemas on a DataCanvas.' It clearly distinguishes from siblings by focusing on schema discovery for a staged openFDA search, and explicitly names openfda_dataframe_query as the follow-up tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit when-to-use guidance: 'Call before openfda_dataframe_query to discover the exact table name, column names, and DuckDB types needed for valid SQL.' This also implies not to use it for querying data itself, and it names the alternative tool.
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 QueryARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | SQL 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_id | Yes | Canvas ID from an openFDA search tool response (the canvas_id field, present when the search ran with stage=true). |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | Rows returned by the query (capped at the canvas row limit). |
| canvas_id | Yes | Canvas ID that was queried — reuse for follow-up queries. |
| row_count | Yes | Number of rows in this response. Equals the canvas row limit when truncated is true. |
| truncated | Yes | True when the result hit the canvas row limit and rows beyond it were dropped. Page the rest with ORDER BY plus LIMIT/OFFSET. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and idempotent behavior, but the description adds valuable context: row limit with truncation/pagination, scalar fields stored as text requiring CAST, nested objects as JSON columns using DuckDB functions, and explicit blocking of DDL/DML/file-reading. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but each sentence contributes essential information: purpose, usage flow, truncation behavior, data type handling, and restrictions. It is front-loaded with the core purpose and remains well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex SQL query tool, the description covers prerequisites (describe), row limit behavior, data type specifics, example usage, and security restrictions. An output schema exists, so return values are not needed in the description. This is comprehensive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers both parameters fully, but the description adds practical usage details: query should use the table name from describe, canvas_id comes from an openFDA search tool response when stage=true. An SQL example further clarifies the query parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs a read-only SQL SELECT against a DataCanvas table staged by an openFDA search tool. It distinguishes itself from sibling tools by focusing on querying staged data, while siblings like openfda_count_values and openfda_dataframe_describe serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs to call openfda_dataframe_describe first for exact table and column names, and notes that the tool enables grouping and aggregation without re-paging the API. It also states restrictions (only SELECT, DDL/DML blocked), which implies when not to use.
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 FieldsARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| endpoint | Yes | openFDA endpoint to describe (e.g. "drug/event", "drug/shortages", "device/510k"). Must be one of the cataloged endpoints. |
Output Schema
| Name | Required | Description |
|---|---|---|
| groups | Yes | Field groups for this endpoint |
| endpoint | Yes | The endpoint these fields apply to |
| queryTips | Yes | openFDA query syntax reminders relevant to this endpoint |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true. The description adds useful context by explaining that the tool groups results by category with type and description, and that field paths are not discoverable from the schema alone. This goes beyond the annotation without contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with the main purpose front-loaded and no filler. Every clause adds value, making it highly scannable and effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter metadata tool with a detailed schema and an output schema present, the description sufficiently covers purpose, usage timing, and output composition. It is complete for what the agent needs to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter endpoint is fully covered by the schema's enum and description (100% coverage). The description reinforces that field paths vary by endpoint but does not add new parameter-level detail beyond what the schema already provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states clearly that it returns the searchable field paths for an openFDA endpoint, grouped by category with type and description. This is a specific metadata/discovery purpose that distinguishes it from sibling query/search tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs 'Use before constructing a search query to find the correct dotted field path' and notes that field names differ per endpoint. It provides clear context for when to use, though it does not explicitly mention when not to use or name alternatives.
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 ProfileARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| drug | Yes | Drug 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Request metadata. |
| label | Yes | Label highlights from drug/label, or null when no label matched. |
| notice | No | Guidance when the drug could not be resolved or upstream errors degraded the profile. Absent on a fully populated profile. |
| recalls | Yes | Recent drug/enforcement recall actions (may be empty). |
| approval | Yes | Drugs@FDA approval summary, or null when no application matched. |
| degraded | Yes | Sub-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. |
| identity | Yes | Identity resolved once and reused across every sub-query to avoid identifier drift. |
| shortage | Yes | Current or most-recent drug shortage status, or null when none on record. |
| sectionsFound | Yes | How many profile sections (label, adverse_events, recalls, approval, shortage) returned data. |
| adverse_events | Yes | Adverse-event summary aggregated over drug/event, or null when unavailable. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses behavioral traits: parallel fan-out, best-effort per-section with null returns instead of failures, and identifier drift reconciliation. This is rich, accurate context that helps the agent predict failure modes and execution model without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences: purpose and contents, differentiation from chaining, and fallback behavior with alternative guidance. Every sentence adds value, no filler, and the most important usage context is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (composite of five endpoints) and the presence of an output schema (which covers return value structure), the description adequately covers execution flow, per-section best-effort behavior, and alternatives. It is complete enough for an agent to select and invoke correctly without further clarification.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema parameter description already includes brand/generic examples and the canonical identifier resolution note. The tool description adds no new parameter-level semantics beyond what the input schema provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool resolves one drug name to FDA identity and merges results from multiple endpoints into a single profile, listing the exact sections (identity, label highlights, adverse events, recalls, approvals, shortages). It explicitly distinguishes itself from siblings by positioning as a replacement for chaining multiple dedicated tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use: 'Replaces chaining...' and when-not-to-use: 'For deep dives into any one area, use the dedicated tool.' It names the exact alternative tools, providing clear guidance for selecting this composite tool vs. focused siblings.
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 LabelARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| search | Yes | Query 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. | |
| sections | No | Label 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
| Name | Required | Description |
|---|---|---|
| cap | No | The limit applied to this page. |
| kind | Yes | Whether this response carries label records ("full") or only the section outline of a page too large to inline ("outline"). |
| meta | Yes | Pagination and freshness metadata. |
| shown | No | Number of labels returned in this response. |
| notice | No | Guidance 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. |
| outline | No | Section 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. |
| results | No | Drug 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. |
| truncated | No | True when more labels matched than this page returned — page with skip for the rest. |
| totalResults | Yes | Total matching label records in the dataset |
| effectiveQuery | Yes | Search filter applied to the drug label query, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses a key behavioral trait: oversized pages return a list of available sections instead of the full label, requiring a re-call with the sections parameter. It also explains the reason (labels run to tens of thousands of tokens), adding valuable context not captured in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary purpose, and every sentence earns its place by adding behavioral context. No redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich input schema (100% coverage) and the presence of an output schema, the description is fully complete. It covers purpose, the main usage scenario, and the critical behavioral quirk (section outline for oversized pages), leaving no ambiguity for the agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds only a brief mention of re-calling with sections, which is already detailed in the schema's sections parameter description. It does not materially enhance parameter understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource pair ('Look up FDA drug labeling') and enumerates concrete use cases (indications, warnings, dosage, etc.), which clearly distinguishes it from sibling tools like adverse events or recalls. It also explains the behavior with sections, adding unique purpose context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use the tool (when needing structured label sections) but does not explicitly name alternatives or exclusions. It says 'Check indications, warnings, dosage...' which establishes context, but lacks an explicit 'use this instead of X' or 'not for Y'.
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 NdcARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| stage | No | Stage 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. | |
| search | Yes | openFDA 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_id | No | DataCanvas 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Response metadata |
| notice | No | Canvas 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. |
| results | Yes | NDC directory records — product_ndc, brand_name, generic_name, labeler_name, dosage_form, route, marketing_category, active_ingredients[], packaging[], listing_expiration_date. |
| spilled | No | True 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_id | No | DataCanvas 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. |
| truncated | No | True 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_bytes | No | Serialized 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_rows | No | Rows 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_table | No | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| page_omitted | No | Records 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. |
| totalResults | Yes | Total matching NDC records in the dataset |
| effectiveQuery | Yes | Search filter applied to the NDC lookup, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool readOnlyHint=true. The description adds the pairing hint about output fields but does not disclose additional runtime behavior such as pagination limits, rate limits, or error conditions (those are covered by the input schema). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exactly two sentences, front-loaded with the core purpose, and every clause earns its place. No redundant repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich input schema, the existing output schema, and readOnly annotation, the description provides sufficient context: it explains the NDC domain, the capabilities, and the natural workflow to get package labels. No critical context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema describes all 6 parameters with 100% coverage, including examples and edge cases. The description adds no additional parameter-level meaning, so it stays at the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Look up drugs in the NDC Directory'), lists concrete capabilities (identify by NDC code, active ingredients, packaging, manufacturer), and distinguishes the tool from sibling openfda_get_drug_label by referencing a pairing workflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a clear workflow: use this tool for NDC directory lookups, then pair with openfda_get_drug_label using brand_name or set_id for the package insert. It doesn't explicitly state exclusions or alternative selections among other siblings, but the context is clear.
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 EventsARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| stage | No | Stage 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. | |
| search | No | openFDA 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. | |
| category | Yes | Product category — each has different field schemas in the response | |
| canvas_id | No | DataCanvas 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Response metadata |
| notice | No | Canvas 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. |
| results | Yes | Adverse event records — fields vary by category (drug: patient/reactions/drugs, device: device details/event type, food: products/outcomes) |
| spilled | No | True 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_id | No | DataCanvas 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. |
| truncated | No | True 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_bytes | No | Serialized 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_rows | No | Rows 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_table | No | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| page_omitted | No | Records 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. |
| totalResults | Yes | Total matching adverse event records in the dataset |
| effectiveQuery | No | Search filter applied to the query, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint=true already discloses the read-only nature, and the description's 'Search' is consistent with that. But the description adds no further behavioral context beyond the schema-provided parameter details—no mention of pagination caps, response size limits, or staging behavior. Since annotations carry the safety profile and the description merely restates the verb, it does not meaningfully advance transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose, and every phrase earns its place. The use-case list is compact and directly useful. No filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main purpose and clearly signals appropriate use cases. Given the rich input schema, output schema, and readOnly annotation, the overall tool context is adequately complete. It doesn't explicitly mention cross-category field differences or the staging option, but those are covered in the schema parameter descriptions, so no critical guidance is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with rich detail on every parameter (e.g., category-specific sort fields, pagination limits, search syntax). The tool description only offers high-level use-case context ('across drugs, food, and devices') that maps to the category parameter but adds no technical meaning beyond what the schema already provides. The baseline of 3 for full schema coverage applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Search adverse event reports across drugs, food, and devices,' which names a specific verb (search), a clear resource (adverse event reports), and an explicit scope (drug, food, device). It also lists concrete use cases (investigating safety signals, product-specific reports, demographic reactions) that distinguish this tool from sibling tools like openfda_search_recalls or openfda_search_drug_approvals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear intended uses: 'investigate safety signals, find reports for a specific product, or explore reactions by demographics.' It does not, however, mention when NOT to use this tool or name alternatives (e.g., openfda_count_values for server-side aggregations), so it falls short of the explicit exclusion/alternative guidance needed for a 5.
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 EventsARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| stage | No | Stage 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. | |
| search | No | openFDA 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_id | No | DataCanvas 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Response metadata |
| notice | No | Canvas 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. |
| results | Yes | Animal 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. |
| spilled | No | True 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_id | No | DataCanvas 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. |
| truncated | No | True 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_bytes | No | Serialized 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_rows | No | Rows 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_table | No | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| page_omitted | No | Records 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. |
| totalResults | Yes | Total matching animal adverse event records in the dataset |
| effectiveQuery | No | Search filter applied to the query, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already communicates the safe read-only nature, so the bar is lower. The description adds useful context about record contents (species, breed, drug name, VeDDRA terminology, outcome), but it does not disclose behavior like pagination limits or return shape beyond what annotations and the rich schema already provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences and front-loaded: purpose, record contents, and usage guidance. Every sentence earns its place, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a fully documented 6-parameter schema, a readOnly annotation, and an output schema, the description supplies the essential scope and search intent. It is complete for a search tool and does not need to restate return values already covered by the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 6 parameters are fully documented in the schema with detailed descriptions, examples, and constraints (e.g., the 25000-record pagination cap and 24000-byte serialized budget). The tool description itself adds no parameter-specific semantics, but at 100% schema coverage the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Search') plus a resource ('adverse event reports for veterinary drugs and devices') and identifies the FDA CVM as the submitting body. It clearly distinguishes this tool from the sibling openfda_search_adverse_events by emphasizing the veterinary/CVM scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit use cases: 'investigate safety signals for veterinary products, find reports by animal species or drug, or explore reaction patterns.' It does not name alternatives or exclusions, but the context makes appropriate use clear.
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 ClearancesARead-onlyInspect
Search FDA device premarket notifications — 510(k) clearances and PMA approvals.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| stage | No | Stage 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. | |
| search | No | openFDA 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. | |
| pathway | Yes | Premarket pathway. 510(k) is the most common; PMA is for higher-risk devices. | |
| canvas_id | No | DataCanvas 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Response metadata |
| notice | No | Canvas 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. |
| results | Yes | 510(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. |
| spilled | No | True 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_id | No | DataCanvas 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. |
| truncated | No | True 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_bytes | No | Serialized 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_rows | No | Rows 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_table | No | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| page_omitted | No | Records 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. |
| totalResults | Yes | Total matching device clearance records in the dataset |
| effectiveQuery | No | Search filter applied to the device clearance query, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, so the read-only safety profile is already known. The description adds the domain scope (510(k) and PMA) which is useful, but it does not mention key behavioral traits such as the pagination cap at 25000 records, the serialized size budget, staging behavior, or query validation rules. These appear in the parameter descriptions, not in the tool description itself, so the top-level description offers modest added transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one compact sentence, front-loaded with the verb and resource, and contains no filler. It efficiently conveys purpose without redundancy, earning a top score for conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the comprehensive schema descriptions and the presence of an output schema, the overall tool definition is complete enough for an agent to select and invoke it correctly. The main description is brief but sufficient for purpose identification; all complex behavioral details are delegated to the parameter descriptions, leaving no critical gaps. A slightly richer top-level description could have helped, but the structured fields fill the need.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, meaning every parameter has its own description, so the baseline is 3. The top-level description adds no parameter-specific guidance beyond what the schema already provides. While the parameter descriptions are rich and include examples, edge cases, and alternatives, that richness is part of the schema, not the tool description, so no extra credit is warrantable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Search' with the resource 'FDA device premarket notifications' and explicitly names the two subtypes '510(k) clearances and PMA approvals'. This unambiguously identifies the tool's domain and distinguishes it from sibling search tools for adverse events, drug approvals, and recalls.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The top-level description pins down the exact use case (device clearance searches), making when-to-use obvious. It lacks an explicit contrast with sibling search tools, but the schema's stage parameter provides a clear alternative ('for a distribution over everything that matched, openfda_count_values aggregates server-side in one request'), giving at least one explicit usage guideline. No exclusions are stated but the context is clear.
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 ApprovalsARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| stage | No | Stage 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. | |
| search | No | openFDA 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_id | No | DataCanvas 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Response metadata |
| notice | No | Canvas 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. |
| results | Yes | Drug 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). |
| spilled | No | True 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_id | No | DataCanvas 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. |
| truncated | No | True 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_bytes | No | Serialized 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_rows | No | Rows 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_table | No | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| page_omitted | No | Records 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. |
| totalResults | Yes | Total matching drug approval records in the dataset |
| effectiveQuery | No | Search filter applied to the Drugs@FDA query, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so no side-effect disclosure is needed. The description adds that the tool returns full submission history, which is a useful behavioral detail, but it does not mention pagination or size constraints (those live in parameter descriptions). With the read-only annotation covering safety, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each with a distinct role: purpose, results, and companion tools. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema and a detailed input schema, the description does not need to explain return values. It provides a clear overview and points to related tools for next steps, though it could briefly contrast with other openFDA search endpoints for full contextual completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 6 parameters have thorough descriptions in the schema, including default values, bounds, and error conditions, so schema description coverage is 100%. The tool description itself does not add parameter semantics beyond the schema, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Search the Drugs@FDA database for drug application approvals (NDAs and ANDAs)', giving a specific verb, resource, and target. It also distinguishes itself from siblings by naming complementary tools, making the scope clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent to pair this with openfda_get_drug_label for labels and openfda_count_values for aggregation, providing clear alternatives for follow-up tasks. However, it does not state when to avoid this tool versus other search tools like openfda_search_adverse_events, falling short of full exclusion guidance.
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 ShortagesARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| stage | No | Stage 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. | |
| search | No | openFDA 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_id | No | DataCanvas 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Response metadata |
| notice | No | Canvas 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. |
| results | Yes | Drug 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. |
| spilled | No | True 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_id | No | DataCanvas 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. |
| truncated | No | True 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_bytes | No | Serialized 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_rows | No | Rows 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_table | No | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| page_omitted | No | Records 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. |
| totalResults | Yes | Total matching drug shortage records in the dataset |
| effectiveQuery | No | Search filter applied to the drug/shortages query, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already communicates that the tool is read-only. The description adds a bit of context about the returned data and chaining possibilities, but it does not disclose any behavioral traits beyond that—no mention of pagination limits, staging side effects, or error conditions. It is not misleading, but it does not enrich the annotation with deeper behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences long and front-loaded with the core action and resource. Every sentence adds value: the first states what it does, the second lists return fields, and the third gives concrete use cases and chaining hints. It is concise, well-structured, and contains no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has six parameters and an output schema, and the description plus schema together cover the essential usage scenarios. The description provides clear use cases and chaining options, while the schema covers parameter nuances like pagination and staging. It does not explicitly mention aggregation alternatives, but the stage parameter description points to openfda_count_values, and the output schema presumably documents return fields. Overall, the description is sufficiently complete for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter has a detailed description (e.g., skip's pagination cap, limit's serialized budget, stage's canvas behavior, search's syntax and examples). The tool description itself adds no parameter-level detail beyond mentioning the returned fields and the openfda block for chaining, which is redundant with schema examples. Since the schema handles parameters thoroughly, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Search FDA drug shortage records'), identifies the endpoint's distinct domain ('drug shortage records'), and enumerates the returned fields ('status, availability, therapeutic category...'). It also differentiates from sibling search tools by naming the resource type and giving concrete use cases, making the tool's purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit use cases: 'check whether a drug is currently in shortage, find all oncology drugs with supply issues, or retrieve the openfda block... to chain into openfda_get_drug_label or openfda_lookup_ndc.' This clearly states when to use the tool, though it does not explicitly say when not to use it or mention alternatives like openfda_count_values for aggregations. The stage parameter description fills some of this gap, but the main description lacks direct exclusion guidance.
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 RecallsARead-onlyInspect
Search enforcement reports and recall actions across drugs, food, and devices.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| stage | No | Stage 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. | |
| search | No | openFDA 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. | |
| category | Yes | Product category | |
| endpoint | No | Report type. Default enforcement. The recall endpoint is only available for devices. | enforcement |
| canvas_id | No | DataCanvas 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Response metadata |
| notice | No | Canvas 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. |
| results | Yes | Enforcement 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. |
| spilled | No | True 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_id | No | DataCanvas 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. |
| truncated | No | True 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_bytes | No | Serialized 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_rows | No | Rows 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_table | No | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| page_omitted | No | Records 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. |
| totalResults | Yes | Total matching recall/enforcement records in the dataset |
| effectiveQuery | No | Search filter applied to the recall query, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description merely states 'Search' with no disclosure of pagination limits, possible errors, or the staging behavior described in the schema. The readOnlyHint annotation covers the safety profile, but the description adds no behavioral context beyond a trivial read-operation implication. It does not contradict the annotation, but it is silent on any side effects or limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence with no filler or redundancy. It delivers the essential purpose without wasting tokens, which is ideal for an agent scanning tool definitions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool with an output schema and a readOnly annotation, a one-sentence description is thin. However, the schema descriptions are exceptionally rich, covering pagination bounds, endpoint availability, and staging semantics. The description is sufficient for a high-level orienting, but it relies heavily on structured fields to provide the full context needed for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for all eight parameters, including detailed semantics for skip, limit, search, and stage. The tool description itself adds no parameter-level information, so it neither helps nor hurts. Baseline 3 is appropriate because the schema already documents every parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Search') and names the resource ('enforcement reports and recall actions') and scope ('drugs, food, and devices'). This distinguishes it from sibling tools like openfda_search_adverse_events, which target a different dataset. It clearly conveys the tool's core function in a single sentence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not mention when to use this tool over alternatives or when not to use it. There are no exclusions or alternative tool references; usage is only implied by the resource scope. The parameter schema does include some endpoint guidance (e.g., recall only for devices), but that is not part of the tool description itself.
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 ReportsARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. | |
| sort | No | Sort 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. | |
| limit | No | Maximum 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. | |
| stage | No | Stage 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. | |
| search | No | openFDA 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_id | No | DataCanvas 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
| Name | Required | Description |
|---|---|---|
| meta | Yes | Response metadata |
| notice | No | Canvas 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. |
| results | Yes | Tobacco 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. |
| spilled | No | True 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_id | No | DataCanvas 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. |
| truncated | No | True 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_bytes | No | Serialized 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_rows | No | Rows 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_table | No | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| page_omitted | No | Records 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. |
| totalResults | Yes | Total matching tobacco problem reports in the dataset |
| effectiveQuery | No | Search filter applied to the query, as submitted to openFDA |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations include readOnlyHint: true, and the description does not contradict this. However, the description adds no behavioral context beyond the read-only hint, such as pagination limits or error conditions (though the schema covers these). Given the annotation, a mid-range 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences: the first states the core action, the second enumerates report contents, and the third lists use cases. Every sentence adds value with no redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a rich schema and output schema present, the description appropriately focuses on domain purpose and typical use cases rather than repeating technical details. It is complete enough for an agent to understand when and why to invoke it, though it does not mention how it relates to sibling aggregation tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents all parameters. The description adds domain context (e.g., report fields like product type and health problems) but does not directly elaborate on parameter usage beyond the schema, aligning with the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Search') and resource ('problem reports submitted to the FDA for tobacco products'), further specifying product categories. This clearly distinguishes it from sibling tools like openfda_search_adverse_events or openfda_count_values.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states clear use cases: 'investigate safety signals, find reports by product type, or analyze health effects.' It provides context for when to use the tool but does not explicitly mention alternatives or exclusions, which would merit a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Claim this connector by publishing a /.well-known/glama.json file on your server's domain with the following structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"maintainers": [{ "email": "your-email@example.com" }]
}The email address must match the email associated with your Glama account. Once published, Glama will automatically detect and verify the file within a few minutes.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Related MCP Servers
- Alicense-qualityAmaintenanceSearch and retrieve US consumer product recalls from the CPSC (Consumer Product Safety Commission) via MCP, with STDIO or Streamable HTTP.1071Apache 2.0
- Flicense-qualityBmaintenanceEnables querying FDA drug approvals, device clearances (510(k)), recalls, and adverse events via the openFDA API, providing tools for clinical and pharmaceutical research.1
- Alicense-qualityAmaintenanceQuery FEMA disaster declarations, public assistance grants, housing aid, and NFIP flood insurance claims via MCP. Supports STDIO and Streamable HTTP.1161Apache 2.0
- Flicense-qualityDmaintenanceEnables searching FDA food recalls and adverse event reports through natural language, supporting filters and pagination.
Your Connectors
Sign in to create a connector for this server.