Skip to main content
Glama

Openfec Search Legal

openfec_search_legal
Read-onlyIdempotent

Search FEC legal documents: advisory opinions, enforcement cases (MURs), alternative dispute resolutions, administrative fines, and statutes. The citation, penalty, respondent, ao_number, and case_number filters each apply to only some document types; with type omitted, the search returns only the types every one of them applies to. Each response is held to 100,000 bytes: when a page would exceed it, whole results are held back and nextFromHit gives the from_hit that continues each document type.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
typeNoDocument type filter. Omit to search every type the other filters apply to — all five when only query is given. admin_fines can be slow without a query.
queryNoFull-text search across legal documents.
from_hitNoOffset for pagination (0-indexed), counted within each document type rather than across them. Default 0. When a response is bounded, nextFromHit gives the value that continues each type. The search index serves a 10,000-result window, so from_hit plus hits_returned must be 10,000 or less — the ceiling here assumes hits_returned of 1.
max_dateNoLatest date (YYYY-MM-DD) for the date_kind selected. Requires type and date_kind.
min_dateNoEarliest date (YYYY-MM-DD) for the date_kind selected. Requires type and date_kind.
ao_numberNoSpecific advisory opinion number (e.g. "2024-01"). Applies to advisory_opinions only: rejected with any other type, and with type omitted only advisory opinions are returned.
date_kindNoWhich date min_date/max_date bound. Each document type records its own dates, so this must be one the chosen type has: type=advisory_opinions → issue_date (opinion issued), request_date (request received), document_date; type=murs or adrs → open_date (case opened), close_date (case closed), document_date; type=admin_fines → rtb_date (reason-to-believe finding), fd_date (final determination). type=statutes cannot be date-filtered. Required whenever min_date or max_date is given, together with type.
respondentNoRespondent name. Applies to enforcement cases (murs, adrs) only: rejected with any other type, and with type omitted only MURs and ADRs are returned.
case_numberNoSpecific MUR, ADR, or administrative fine case number (e.g. "8343"). Applies to murs, adrs, and admin_fines: rejected with advisory_opinions or statutes, and with type omitted only those three types are returned.
hits_returnedNoResults per page, applied per document type. Default 20, max 200. A response is held to 100,000 bytes, so a page of large records can carry fewer, with nextFromHit naming where each type continues. Bounded together with from_hit by the 10,000-result window.
max_penalty_amountNoMaximum penalty amount in dollars. Applies to murs, adrs, and admin_fines (an administrative fine matches on its reason-to-believe or final-determination amount): rejected with advisory_opinions or statutes, and with type omitted only those three types are returned.
min_penalty_amountNoMinimum penalty amount in dollars. Applies to murs, adrs, and admin_fines (an administrative fine matches on its reason-to-believe or final-determination amount): rejected with advisory_opinions or statutes, and with type omitted only those three types are returned.
statutory_citationNoU.S.C. citation in the form "<title> U.S.C. <section>" (e.g. "52 U.S.C. 30104"; "USC", "§", and a suffix such as "30104(g)" are accepted — a bare "30104" is rejected as invalid_citation). One citation per value: "52 U.S.C. 30104, 52 U.S.C. 30118" is rejected, since only the first would be applied. Given with regulatory_citation, matches a document that cites either one. On murs and adrs it cannot be combined with case_number, respondent, a penalty bound, or an open_date or close_date bound, which the search index would ignore. Applies to advisory_opinions, murs, and adrs: rejected with admin_fines or statutes, and with type omitted only those three types are returned.
regulatory_citationNoCFR citation in the form "<title> CFR <part>.<section>" (e.g. "11 CFR 110.1"; "C.F.R.", "§", and a suffix such as "110.1(b)" are accepted — a bare "110.1" is rejected as invalid_citation). One citation per value: "11 CFR 110.1; 11 CFR 110.2" is rejected, since only the first would be applied. Given with statutory_citation, matches a document that cites either one. On murs and adrs it cannot be combined with case_number, respondent, a penalty bound, or an open_date or close_date bound, which the search index would ignore. Applies to advisory_opinions, murs, and adrs: rejected with admin_fines or statutes, and with type omitted only those three types are returned.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
shownNoResults in this response. Present only when truncated is true.
noticeNoGuidance on the page returned: how to broaden a search that matched nothing, that from_hit ran past the end when documents did match, or — when truncated is set — how each document type continues.
resultsNoLegal document result set spanning advisory opinions, MURs, ADRs, admin fines, and statutes — only the types searched. Grouped by type in upstream order; when truncated is set, each type holds its first results up to the response budget.
truncatedNoTrue when results upstream returned for this page were held back because the next one would take the response past its 100,000-byte budget. Absent when the page is complete, including a naturally short page and an offset past the end.
totalCountNoTotal matching legal documents across the document types searched.
nextFromHitNoThe from_hit that continues each document type with results held back, keyed by the value to pass as type (advisory_opinions, murs, adrs, admin_fines, statutes). Re-call with the same filters, that type, and this from_hit. Present only when truncated is true.
total_countNoTotal matching documents across the types searched: the requested type, or with type omitted, every type the supplied filters apply to.
retrievalHintNoHow to recover the material trimmed out of these results. Present whenever any result was returned, because every result is trimmed.
search_criteriaNoEcho of the search filters this call applied, as the server parsed them, minus paging arguments. Always present — compare it against what you sent to confirm every filter was honoured.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed20 schema fields changed
    • changedInput schema / properties / ao_number / description
      Previous value: -"Specific advisory opinion number (e.g. \"2024-01\")."New value: +"Specific advisory opinion number (e.g. \"2024-01\"). Applies to advisory_opinions only: rejected with any other type, and with type omitted only advisory opinions are returned."
    • changedInput schema / properties / case_number / description
      Previous value: -"Specific MUR or ADR case number."New value: +"Specific MUR, ADR, or administrative fine case number (e.g. \"8343\"). Applies to murs, adrs, and admin_fines: rejected with advisory_opinions or statutes, and with type omitted only those three types are returned."
    • changedInput schema / properties / from_hit / description
      Previous value: -"Offset for pagination (0-indexed), counted within each document type rather than across them. Default 0. The search index serves a 10,000-result window, so from_hit plus hits_returned must be 10,000 or less — the ceiling here assumes hits_returned of 1."New value: +"Offset for pagination (0-indexed), counted within each document type rather than across them. Default 0. When a response is bounded, nextFromHit gives the value that continues each type. The search index serves a 10,000-result window, so from_hit plus hits_returned must be 10,000 or less — the ceiling here assumes hits_returned of 1."
    • changedInput schema / properties / hits_returned / description
      Previous value: -"Results per page, applied per document type. Default 20, max 200. Bounded together with from_hit by the 10,000-result window."New value: +"Results per page, applied per document type. Default 20, max 200. A response is held to 100,000 bytes, so a page of large records can carry fewer, with nextFromHit naming where each type continues. Bounded together with from_hit by the 10,000-result window."
    • changedInput schema / properties / max_penalty_amount / description
      Previous value: -"Maximum penalty amount in dollars. Filters enforcement cases (murs, adrs) only — other document types are returned unfiltered by it."New value: +"Maximum penalty amount in dollars. Applies to murs, adrs, and admin_fines (an administrative fine matches on its reason-to-believe or final-determination amount): rejected with advisory_opinions or statutes, and with type omitted only those three types are returned."
    • changedInput schema / properties / min_penalty_amount / description
      Previous value: -"Minimum penalty amount in dollars. Filters enforcement cases (murs, adrs) only — other document types are returned unfiltered by it."New value: +"Minimum penalty amount in dollars. Applies to murs, adrs, and admin_fines (an administrative fine matches on its reason-to-believe or final-determination amount): rejected with advisory_opinions or statutes, and with type omitted only those three types are returned."
    • changedInput schema / properties / regulatory_citation / description
      Previous value: -"CFR citation (e.g. \"11 CFR 112.4\")."New value: +"CFR citation in the form \"<title> CFR <part>.<section>\" (e.g. \"11 CFR 110.1\"; \"C.F.R.\", \"§\", and a suffix such as \"110.1(b)\" are accepted — a bare \"110.1\" is rejected as invalid_citation). One citation per value: \"11 CFR 110.1; 11 CFR 110.2\" is rejected, since only the first would be applied. Given with statutory_citation, matches a document that cites either one. On murs and adrs it cannot be combined with case_number, respondent, a penalty bound, or an open_date or close_date bound, which the search index would ignore. Applies to advisory_opinions, murs, and adrs: rejected with admin_fines or statutes, and with type omitted only those three types are returned."
    • changedInput schema / properties / respondent / description
      Previous value: -"Respondent name (enforcement cases)."New value: +"Respondent name. Applies to enforcement cases (murs, adrs) only: rejected with any other type, and with type omitted only MURs and ADRs are returned."
    • changedInput schema / properties / statutory_citation / description
      Previous value: -"U.S.C. citation (e.g. \"52 U.S.C. 30106\")."New value: +"U.S.C. citation in the form \"<title> U.S.C. <section>\" (e.g. \"52 U.S.C. 30104\"; \"USC\", \"§\", and a suffix such as \"30104(g)\" are accepted — a bare \"30104\" is rejected as invalid_citation). One citation per value: \"52 U.S.C. 30104, 52 U.S.C. 30118\" is rejected, since only the first would be applied. Given with regulatory_citation, matches a document that cites either one. On murs and adrs it cannot be combined with case_number, respondent, a penalty bound, or an open_date or close_date bound, which the search index would ignore. Applies to advisory_opinions, murs, and adrs: rejected with admin_fines or statutes, and with type omitted only those three types are returned."
    • changedInput schema / properties / type / description
      Previous value: -"Document type filter. Omit to search all types. admin_fines is slow without a query or respondent filter."New value: +"Document type filter. Omit to search every type the other filters apply to — all five when only query is given. admin_fines can be slow without a query."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `missing_filter`: Called without any scoping filter at all. `date_filter_incomplete`: min_date or max_date given without both a type and a date_kind, or a date_kind given with neither bound. `date_kind_not_valid_for_type`: The requested date_kind is not a date this document type records. `legal_window_exceeded`: from_hit plus hits_returned exceeds the 10,000-result window the search index serves. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `missing_filter`: Called without any scoping filter at all. `date_filter_incomplete`: min_date or max_date given without both a type and a date_kind, or a date_kind given with neither bound. `date_kind_not_valid_for_type`: The requested date_kind is not a date this document type records. `filter_not_valid_for_type`: A type-specific filter was sent with a type it does not filter, or type-specific filters that no single document type accepts together — including a citation with case_number, respondent, a penalty bound, or an open_date or close_date bound on murs or adrs. `invalid_citation`: A citation is not in a form the search index parses, so upstream would ignore it and return the type unfiltered, or a value holds a second citation upstream would ignore. `legal_window_exceeded`: from_hit plus hits_returned exceeds the 10,000-result window the search index serves. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "missing_filter",
      -  "date_filter_incomplete",
      -  "date_kind_not_valid_for_type",
      -  "legal_window_exceeded"
      -]New value: +[
      +  "missing_filter",
      +  "date_filter_incomplete",
      +  "date_kind_not_valid_for_type",
      +  "filter_not_valid_for_type",
      +  "invalid_citation",
      +  "legal_window_exceeded"
      +]
    • addedOutput schema / properties / nextFromHit
      Added value: +{
      +  "additionalProperties": {
      +    "type": "number"
      +  },
      +  "description": "The from_hit that continues each document type with results held back, keyed by the value to pass as type (advisory_opinions, murs, adrs, admin_fines, statutes). Re-call with the same filters, that type, and this from_hit. Present only when truncated is true.",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when the response carries no legal documents: how to broaden a search that matched nothing, or that from_hit ran past the end when documents did match."New value: +"Guidance on the page returned: how to broaden a search that matched nothing, that from_hit ran past the end when documents did match, or — when truncated is set — how each document type continues."
    • changedOutput schema / properties / results / description
      Previous value: -"Legal document result set spanning advisory opinions, MURs, ADRs, admin fines, and statutes."New value: +"Legal document result set spanning advisory opinions, MURs, ADRs, admin fines, and statutes — only the types searched. Grouped by type in upstream order; when truncated is set, each type holds its first results up to the response budget."
    • changedOutput schema / properties / results / items / description
      Previous value: -"Legal document record. The document_type field discriminates among advisory_opinion, mur, adr, admin_fine, and statute. Common fields include no (the identifier every type carries, and the one openfec_get_legal_document takes; advisory opinions repeat it as ao_no), name, document_type, document_count, and document_categories summarizing the related filings."New value: +"Legal document record. The document_type field discriminates among advisory_opinion, mur, adr, admin_fine, and statute. Common fields include no (the identifier every type carries, and the one openfec_get_legal_document takes; advisory opinions repeat it as ao_no), name, document_type, document_count and document_categories summarizing the related filings, and disposition_count and disposition_categories summarizing the dispositions."
    • addedOutput schema / properties / shown
      Added value: +{
      +  "description": "Results in this response. Present only when truncated is true.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / totalCount / description
      Previous value: -"Total matching legal documents across all types."New value: +"Total matching legal documents across the document types searched."
    • changedOutput schema / properties / total_count / description
      Previous value: -"Total matching documents across all types."New value: +"Total matching documents across the types searched: the requested type, or with type omitted, every type the supplied filters apply to."
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when results upstream returned for this page were held back because the next one would take the response past its 100,000-byte budget. Absent when the page is complete, including a naturally short page and an offset past the end.",
      +  "type": "boolean"
      +}
  2. Changed6 schema fields changed
    • changedInput schema / properties / from_hit / description
      Previous value: -"Offset for pagination (0-indexed). Default 0."New value: +"Offset for pagination (0-indexed), counted within each document type rather than across them. Default 0. The search index serves a 10,000-result window, so from_hit plus hits_returned must be 10,000 or less — the ceiling here assumes hits_returned of 1."
    • changedInput schema / properties / from_hit / maximum
      Previous value: -9007199254740991New value: +9999
    • changedInput schema / properties / hits_returned / description
      Previous value: -"Results per page. Default 20, max 200."New value: +"Results per page, applied per document type. Default 20, max 200. Bounded together with from_hit by the 10,000-result window."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `missing_filter`: Called without any scoping filter at all. `date_filter_incomplete`: min_date or max_date given without both a type and a date_kind, or a date_kind given with neither bound. `date_kind_not_valid_for_type`: The requested date_kind is not a date this document type records. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `missing_filter`: Called without any scoping filter at all. `date_filter_incomplete`: min_date or max_date given without both a type and a date_kind, or a date_kind given with neither bound. `date_kind_not_valid_for_type`: The requested date_kind is not a date this document type records. `legal_window_exceeded`: from_hit plus hits_returned exceeds the 10,000-result window the search index serves. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "missing_filter",
      -  "date_filter_incomplete",
      -  "date_kind_not_valid_for_type"
      -]New value: +[
      +  "missing_filter",
      +  "date_filter_incomplete",
      +  "date_kind_not_valid_for_type",
      +  "legal_window_exceeded"
      +]
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when no legal documents matched — echoes filters and suggests how to broaden."New value: +"Guidance when the response carries no legal documents: how to broaden a search that matched nothing, or that from_hit ran past the end when documents did match."
  3. Changed1 schema field changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `missing_filter`: Called without any scoping filter at all `date_filter_incomplete`: min_date or max_date given without both a type and a date_kind, or a date_kind given with neither bound `date_kind_not_valid_for_type`: The requested date_kind is not a date this document type records Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `missing_filter`: Called without any scoping filter at all. `date_filter_incomplete`: min_date or max_date given without both a type and a date_kind, or a date_kind given with neither bound. `date_kind_not_valid_for_type`: The requested date_kind is not a date this document type records. Other values are possible when a failure originates below the handler."
  4. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "results",
      +      "total_count",
      +      "search_criteria",
      +      "totalCount"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `missing_filter`: Called without any scoping filter at all `date_filter_incomplete`: min_date or max_date given without both a type and a date_kind, or a date_kind given with neither bound `date_kind_not_valid_for_type`: The requested date_kind is not a date this document type records Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "missing_filter",
      +            "date_filter_incomplete",
      +            "date_kind_not_valid_for_type"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "results",
      -  "total_count",
      -  "search_criteria",
      -  "totalCount"
      -]
  5. Changed2 schema fields changed
    • changedOutput schema / properties / results / items / description
      Previous value: -"Legal document record. The document_type field discriminates among advisory_opinion, mur, adr, admin_fine, and statute. Common fields include ao_no/case_no/no (identifier), name, document_type, document_count, and document_categories summarizing the related filings."New value: +"Legal document record. The document_type field discriminates among advisory_opinion, mur, adr, admin_fine, and statute. Common fields include no (the identifier every type carries, and the one openfec_get_legal_document takes; advisory opinions repeat it as ao_no), name, document_type, document_count, and document_categories summarizing the related filings."
    • addedOutput schema / properties / retrievalHint
      Added value: +{
      +  "description": "How to recover the material trimmed out of these results. Present whenever any result was returned, because every result is trimmed.",
      +  "type": "string"
      +}
  6. Changed2 schema fields changed
    • changedOutput schema / properties / search_criteria / description
      Previous value: -"Echo of the search filters that produced this result set. Populated when results are empty to help diagnose why nothing matched."New value: +"Echo of the search filters this call applied, as the server parsed them, minus paging arguments. Always present — compare it against what you sent to confirm every filter was honoured."
    • changedOutput schema / required
      Previous value: -[
      -  "results",
      -  "total_count",
      -  "totalCount"
      -]New value: +[
      +  "results",
      +  "total_count",
      +  "search_criteria",
      +  "totalCount"
      +]
  7. Changed5 schema fields changed
    • addedInput schema / properties / date_kind
      Added value: +{
      +  "description": "Which date min_date/max_date bound. Each document type records its own dates, so this must be one the chosen type has: type=advisory_opinions → issue_date (opinion issued), request_date (request received), document_date; type=murs or adrs → open_date (case opened), close_date (case closed), document_date; type=admin_fines → rtb_date (reason-to-believe finding), fd_date (final determination). type=statutes cannot be date-filtered. Required whenever min_date or max_date is given, together with type.",
      +  "enum": [
      +    "issue_date",
      +    "request_date",
      +    "open_date",
      +    "close_date",
      +    "document_date",
      +    "rtb_date",
      +    "fd_date"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / max_date / description
      Previous value: -"Latest document date (YYYY-MM-DD)."New value: +"Latest date (YYYY-MM-DD) for the date_kind selected. Requires type and date_kind."
    • changedInput schema / properties / max_penalty_amount / description
      Previous value: -"Maximum penalty amount."New value: +"Maximum penalty amount in dollars. Filters enforcement cases (murs, adrs) only — other document types are returned unfiltered by it."
    • changedInput schema / properties / min_date / description
      Previous value: -"Earliest document date (YYYY-MM-DD)."New value: +"Earliest date (YYYY-MM-DD) for the date_kind selected. Requires type and date_kind."
    • changedInput schema / properties / min_penalty_amount / description
      Previous value: -"Minimum penalty amount (enforcement cases)."New value: +"Minimum penalty amount in dollars. Filters enforcement cases (murs, adrs) only — other document types are returned unfiltered by it."
  8. Changed2 schema fields changed
    • addedOutput schema / properties / totalCount
      Added value: +{
      +  "description": "Total matching legal documents across all types.",
      +  "type": "number"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "results",
      -  "total_count"
      -]New value: +[
      +  "results",
      +  "total_count",
      +  "totalCount"
      +]
  9. Changed1 schema field changed
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Guidance when no legal documents matched — echoes filters and suggests how to broaden.",
      +  "type": "string"
      +}
  10. Changed2 schema fields changed
    • changedOutput schema / properties / results / description
      Previous value: -"Legal documents with a document_type discriminator (advisory_opinion, mur, adr, admin_fine, statute)."New value: +"Legal document result set spanning advisory opinions, MURs, ADRs, admin fines, and statutes."
    • changedOutput schema / properties / results / items / description
      Previous value: -"A legal document record with a document_type discriminator (advisory_opinion, mur, adr, admin_fine, statute)."New value: +"Legal document record. The document_type field discriminates among advisory_opinion, mur, adr, admin_fine, and statute. Common fields include ao_no/case_no/no (identifier), name, document_type, document_count, and document_categories summarizing the related filings."
  11. Changed1 schema field changed
    • addedOutput schema / properties / results / items / description
      Added value: +"A legal document record with a document_type discriminator (advisory_opinion, mur, adr, admin_fine, statute)."
  12. Changed4 schema fields changed
    • addedOutput schema / properties / results / items / properties
      Added value: +{}
    • removedOutput schema / properties / results / items / propertyNames
      Removed value: -{
      -  "type": "string"
      -}
    • addedOutput schema / properties / search_criteria / properties
      Added value: +{}
    • removedOutput schema / properties / search_criteria / propertyNames
      Removed value: -{
      -  "type": "string"
      -}
  13. First observed

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, so the description does not need to restate safety. It adds valuable behavioral context: the 100,000-byte response limit, how whole results are held back, and that nextFromHit continues each document type. It also notes that admin_fines can be slow without a query (in the type parameter). This goes beyond the annotations and enriches the agent's understanding of the tool's runtime behavior.

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

Conciseness5/5

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

The description is exactly two sentences, front-loaded with the primary purpose and then the key behavioral constraints. Every clause earns its place: the document types, the filter-scoping rule, and the pagination/byte-limit behavior. No fluff or redundancy.

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

Completeness4/5

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

Given the tool's complexity (14 parameters, no required, output schema present), the description covers the essential high-level behaviors: what the tool searches, how type-scoped filters work, and the response size/pagination mechanism. The output schema exists, so the description need not explain return values. It does not mention error cases or rate limits, but those are not critical for correct invocation. Slight gap: it doesn't explicitly state that the tool is read-only (though annotations cover that), and it doesn't summarize the output structure beyond nextFromHit. Still, it is adequate for an agent to call it correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so every parameter already has a thorough description in the schema (e.g., type, from_hit, date_kind, citations). The main description adds some high-level context about filter interactions (e.g., 'with type omitted, the search returns only the types every one of them applies to') and the byte limit, but it does not clarify individual parameter syntax beyond what the schema already provides. Baseline of 3 is appropriate since the schema carries the burden.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Search FEC legal documents' and enumerates the exact document types (advisory opinions, MURs, ADRs, admin fines, statutes). It is specific and distinct from sibling tools like openfec_get_legal_document, which retrieves a specific document, and other search tools for candidates/committees. No ambiguity or tautology.

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

Usage Guidelines4/5

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

The description provides clear context on when to use the tool (searching legal documents) and explains critical behavior like the filter applicability (only some document types) and the byte-limit pagination. However, it does not explicitly state when NOT to use it (e.g., when a specific document is needed, use openfec_get_legal_document). The guidance is strong but lacks an explicit exclusion.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.