Skip to main content
Glama

Ansvar: EU Compliance & Legal Intelligence

Search

search
Read-only

Search requires at least one jurisdiction, framework, sector, or source; it does not auto-detect scope from the query. Use for 'what does the law say about X in country Y' or 'which regulations cover Z'. QUERY SHAPE: queries are keyword-matched (FTS5, implicit AND — every term must occur in the SAME provision). Pass one or two canonical concept terms per call; never a multi-concept compound. A compound such as 'incident reporting deadline personal data breach' returns 0 even when each concept on its own returns hits — so ask one concept per call and combine the answers yourself. Two terms describing ONE concept ('personal data') are fine; 2-3 alternative terms can be joined with a bare uppercase OR (e.g. 'spoofing OR tampering' matches either term). OR is for synonyms of ONE concept, not for related concepts — 'dismissal OR termination' yes, 'encryption OR breach notification' no (ask those one per call). Other FTS operators (AND, NOT, NEAR) are stripped. IDENTIFIERS: premium+ resolves an ECLI in the query (Dutch scope: a capitalised LJN, e.g. BZ7274) exactly; the hit leads with match_mode='exact_identifier'; a miss is named in meta.identifier_resolution. STRICT MISS: when a search completes cleanly and no result matched your terms strictly, the response carries meta.outcome = 'NO_STRICT_MATCH'. The recovery fields — meta.recommended_action, meta.recommended_scopes, meta.broadening_available — are set on any qualifying strict miss, INCLUDING a partial fan-out where outcome stays null, so read them whenever present, not only under an outcome. On a partial fan-out meta.broadening_available stays null when the missing leg makes it unknowable — null there means unknown, never 'no'. On recommended_action = 'RETRY_ONE_CONCEPT_PER_CALL', re-issue the search with ONE concept per call. This action is reserved for an implicit-AND multi-concept compound; an honored uppercase-OR query remains a canonical one-concept shape and does not gain the split action or candidates. Only together with this action, meta.recommended_queries may list 1-3 optional one-concept fallback queries derived from your own terms, each already checked in your scope to return a strict match (verified_hits; rows not merged); issue only the ones you judge relevant, one per call. The field is absent for every other action or no action, including an honored uppercase-OR miss. On a miss without safe candidates, meta.recovery_guidance explains how to choose a focused phrase while retaining domain and negation; its source_languages are source metadata, not your query's detected language. On 'REFORMULATE_OR_USE_EXACT_REFERENCE', retry the same concept using the instrument's wording or use an exact lookup hint. Short queries can miss too; do not infer that the law is absent. On recommended_action = 'OFFER_BROADENING_TO_USER' — and wherever meta.broadening_available is true — relaxed matches exist and are withheld: tell the user, offer a re-run with allow_broadening=true (served rows are stamped match_mode='broadened' and pass the same relevance floor), and re-run only if the user accepts — never broaden on your own. An honored uppercase-OR strict miss with withheld relaxed matches carries this offer action with meta.recommended_queries absent. meta.recommended_scopes names scope ids that were not searched. If 0 results, tell the user; do not answer from training data. SCOPE: discover ids with list_coverage or describe_capabilities(section='sources'). An unresolved scope refuses before dispatch with isError=true and structuredContent.error='unresolved_scope'. Read corrections for the offending parameter and optional registered values. Choose the intended scope; suggestions do not establish legal equivalence. Change only the offending value and retain other arguments. frameworks= selects sources declaring coverage. Non-owner rows require the requested framework identity to serve as strict matches; otherwise they are withheld with a count, or served as broadened matches when allow_broadening=true. Framework scope does not map controls to transposition articles. For cross-framework control mapping, frameworks=['ISO_27001','SOC_2'] includes Security Controls MCP. sectors= reaches industry MCPs across jurisdictions; combining jurisdictions= and sectors= is an INTERSECTION and an empty intersection errors with the jurisdictions that carry that sector. Use sources=['data-use-license'] for software licences, SPDX, dataset licences, and vendor TOS. LANGUAGE: use the corpus language (SE: konsumentskydd; DE: Datenschutz; FR: protection des consommateurs). Keep CJK compounds unspaced (個人情報保護, not 個人情報 保護); spaced tokens are ANDed. Examples: search(query='konsumentskydd', jurisdictions=['SE']); search(query='vehicle cybersecurity', sectors=['automotive']); search(query='huurovereenkomst', jurisdictions=['NL'], court='GHAMS', date_from='2023-01-01') filters case-law rows (premium+); read exact court values from unfiltered results first. TIER LIMITS: free permits at most one value per jurisdiction, framework, or source axis; no sectors= or premium fan-out, with 100 searches/day and 3 concurrent calls. Daily search budgets: solo 750/seat; premium 5,000/seat; team 50,000 and company 500,000 pooled per organisation. Solo lifts scope limits; premium+ adds server-side fan-out to agency guidance, case law, and preparatory works alongside primary legislation. There is no separate search_case_law or search_preparatory_works tool; search_guidance can search guidance alone. Call get_my_capabilities for your budget and remaining quota. RANKING: requested rows precede injected companion rows; explicit sources and sectors remain requested. Where primary-law window fill is enabled, the quota-protected primary-lane prefix precedes premium companion rows while retaining fused order. A jurisdiction-only search may retain up to half the window (rounded up) for primary-law rows that matched the caller's own terms — strict first, then the exact term-bridge tail, never a broadened one — before filling remaining slots from the fused ranking; explicit source, framework, and sector scope membership is unchanged. The text content is one JSON document. Its evidence_summary field carries the 'Sources used' markdown table (the audit receipt per returned row) or a labelled zero-result note. Result rows carry url/title/subtitle display fields alongside their citation when available. meta.render_contract carries the versioned evidence-curation contract. Search in the corpus's primary language (en), then fetch the hits in the user's language with the language argument of get_provision (a code, or a short list of codes for versions side by side).

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "query": "<query>"
    },
    "name": "search"
  }
}

Input Schema

NameRequiredDescriptionDefault
courtNoFilter on the issuing court of case-law rows: the corpus's own `court` value exactly as its case-law rows carry it (Dutch courts are codes such as HR, RVS, CRVB, CBB, GHAMS, RBDHA; other corpora may carry a court name), or a court prefix ending in '*' (every court value of the corpus starting with it, e.g. 'GH*' for the Dutch courts of appeal; '*' only as the last character). For several courts pass `courts` instead. Read values from the `court` field of case-law rows returned without the filter before filtering. Applies to case-law evidence only, which premium+ fan-out adds inside `search`; primary-law provisions have no court and are unaffected. A filter that matches no case-law row is disclosed in meta.message, never served as a silent empty. A value that is not a court of any case-law source searched (and matched no row) refuses with isError=true and the unresolved_scope body: corrections carry close court values and each source's court list. A source whose runtime cannot apply a prefix yet is reported failed for that call, never served unfiltered. Refused on tiers without case-law fan-out.
limitNoMaximum result rows in the response (default 10) — rows from all resolved sources are relevance-fused, deduplicated, and trimmed to this count. Values above 50 are clamped to 50, not rejected; narrow the scope or refine the query instead of raising the limit.
queryYesSearch terms, matched with FTS5 implicit AND against each resolved corpus. Pass one or two canonical concept terms in the corpus language (SE: konsumentskydd, DE: Datenschutz), never a multi-concept compound. A bare uppercase OR between 2-3 terms is honoured as a disjunction (either term matches); other uppercase FTS operators (AND, NOT, NEAR) are stripped, not honoured. At most 500 characters: a longer query (a pasted case description, say) is refused before any source is searched, with isError=true and structuredContent error='validation_error', code='query_too_long'. Split the matter into separate issue queries of 2-5 legal terms, one call per issue, and merge the results. A court-decision identifier in the query (an ECLI; in Dutch scope a capitalised LJN) is looked up exactly on premium+: meta.identifier_resolution lists each one with status resolved, not_found or failed and the source ids searched. On not_found, meta.message says the decision is not in Ansvar, and rows that only cite it carry match_mode='cites_identifier' (not a strict answer).
courtsNoSeveral court filters at once: 1 to 20 values, each a court value exactly as case-law rows carry it or a prefix ending in '*' (e.g. ['GHARL', 'GHAMS'] or ['GH*', 'HR']); rows of any of them are returned. Same rules as `court`; pass `court` or `courts`, not both. A value of the list that is no court of any source searched is named in meta.message while the other values are applied; when none is, the call refuses as for `court`. A source whose runtime cannot apply a list yet is reported failed for that call, never served unfiltered.
date_toNoInclusive upper bound as a full ISO date YYYY-MM-DD on the decision date of case-law rows and the issue date of preparatory-work and agency-guidance rows; must not precede date_from. Premium+ evidence only; primary-law provisions are unaffected.
sectorsNoIndustry-sector scope ids such as automotive or insurance; maximum 5. Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query.
sourcesNoExact corpus source ids such as eu-regulations or ietf-rfcs, read from describe_capabilities(section='sources') — never a hash, UUID, or document reference; a country code such as LI or DE belongs in jurisdictions=, not here. Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query.
date_fromNoInclusive lower bound as a full ISO date YYYY-MM-DD (a bare year such as 2023 is refused — pass 2023-01-01) on the decision date of case-law rows and the issue date of preparatory-work and agency-guidance rows. Premium+ evidence only; primary-law provisions carry no date and are unaffected.
frameworksNoRegistered framework scope ids such as GDPR or NIS2 — never a jurisdiction code (LI, DE, EU go in jurisdictions=). Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query.
legal_areasNoPublisher area-of-law ids, for the corpora that carry them; maximum 10. Ids are the publisher's own, case-sensitive (Rechtspraak: civielRecht, civielRecht_verbintenissenrecht; wetten.overheid.nl carries its own rechtsgebied ids), and a parent id also matches its sub-areas. Statute and regulation rows carry the area of the WHOLE act, so a hit is an article of an act classified in that area; court decisions carry the court's own area for each decision. The filter reaches legislation and case-law rows only — agency-guidance and preparatory-works rows are never area-filtered. A corpus that carries no area metadata serves its rows unfiltered; when at least one source applied the filter, unfiltered rows rank behind the filtered ones and fill at most two thirds of the window, so a filtered search can return fewer rows than limit (the count held out is in meta.search_scope.legal_areas_unfiltered_dropped). Every source that served unfiltered rows is named under meta.search_scope.legal_areas_not_applied with a reason (corpus_unclassified, no_envelope, not_forwarded), the sources that applied it under legal_areas_applied, and any id a corpus does not know under legal_areas_unknown_ids; a zero-row answer for a known id is a real answer. A source that knows NONE of the requested ids returns no rows under the filter: meta.message names it, and an empty answer carries recommended_action = 'CHECK_LEGAL_AREA_IDS' (drop legal_areas or add an id from that source's scheme). Legal order stays on jurisdictions=: legal_areas=['civielRecht'] with jurisdictions=['NL','EU'] filters the Dutch case-law rows and keeps the EU rows, flagged unfiltered. No tier gate.
workflow_idNoId of the caller's own active included workflow run (Free and Solo), when this search is part of that run. Searches that name the run draw from its own allowance of 300 searches instead of the daily search budget, so a run is not cut off by the daily limit. At the run allowance the search is refused with cap='run_search_allowance'; it does not spill onto the daily budget. An id the gateway cannot verify as an active run you started (unknown, ended, or another account's) is not an error: the daily budget applies. Ignored on Premium, Team and Company, whose daily budgets a run does not reach. Does not change what is searched.
document_refsNoExact edition keys from document discovery; 1–5 unique elx- keys with 24 lowercase hex digits. Accepted only with one sources entry advertising exact_document_filter and no jurisdictions, frameworks or sectors. Keys are OR-combined within that source.
jurisdictionsNoISO-2 jurisdiction scope codes such as SE or EU; maximum 10. A country code such as LI or DE belongs here and on no other axis. Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query.
allow_broadeningNoControlled-vocabulary term_bridge rows serve at the default, stamped match_mode='bridged'; meta.query_broadened_sources discloses requested_query, served_query and mode. Default false: a source that finds no strict match for the query is withheld instead of serving relaxed (OR-broadened) matches as if they were ordinary hits; the response names the withheld sources and count. Pass true to include those rows — each is stamped match_mode='broadened' — only after the user has accepted a broaden offer or asked for relaxed matches; never broaden unprompted. Relaxed rows pass the same on-topic relevance floor as strict rows, so an accepted re-run can still withhold them — disclosed in the response, never silently served.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / court / description
      Previous value: -"Exact-match filter on the issuing court of case-law rows: the corpus's own `court` value exactly as its case-law rows carry it (Dutch courts are codes such as HR, RVS, CRVB, CBB, GHAMS, RBDHA; other corpora may carry a court name). Read the value from the `court` field of case-law rows returned without the filter before filtering. Applies to case-law evidence only, which premium+ fan-out adds inside `search`; primary-law provisions have no court and are unaffected. A value that matches no case-law row is disclosed in meta.message, never served as a silent empty. A value that is not a court of any case-law source searched (and matched no row) refuses with isError=true and the unresolved_scope body: corrections[0] carries close court values and each source's court list. One court per call. Refused on tiers without case-law fan-out."New value: +"Filter on the issuing court of case-law rows: the corpus's own `court` value exactly as its case-law rows carry it (Dutch courts are codes such as HR, RVS, CRVB, CBB, GHAMS, RBDHA; other corpora may carry a court name), or a court prefix ending in '*' (every court value of the corpus starting with it, e.g. 'GH*' for the Dutch courts of appeal; '*' only as the last character). For several courts pass `courts` instead. Read values from the `court` field of case-law rows returned without the filter before filtering. Applies to case-law evidence only, which premium+ fan-out adds inside `search`; primary-law provisions have no court and are unaffected. A filter that matches no case-law row is disclosed in meta.message, never served as a silent empty. A value that is not a court of any case-law source searched (and matched no row) refuses with isError=true and the unresolved_scope body: corrections carry close court values and each source's court list. A source whose runtime cannot apply a prefix yet is reported failed for that call, never served unfiltered. Refused on tiers without case-law fan-out."
    • addedInput schema / properties / courts
      Added value: +{
      +  "description": "Several court filters at once: 1 to 20 values, each a court value exactly as case-law rows carry it or a prefix ending in '*' (e.g. ['GHARL', 'GHAMS'] or ['GH*', 'HR']); rows of any of them are returned. Same rules as `court`; pass `court` or `courts`, not both. A value of the list that is no court of any source searched is named in meta.message while the other values are applied; when none is, the call refuses as for `court`. A source whose runtime cannot apply a list yet is reported failed for that call, never served unfiltered.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "title": "Courts",
      +  "type": "array"
      +}
  2. Changed2 schema fields changed
    • changedInput schema / properties / court / description
      Previous value: -"Exact-match filter on the issuing court of case-law rows: the corpus's own `court` value exactly as its case-law rows carry it (Dutch courts are codes such as HR, RVS, CRVB, CBB, GHAMS, RBDHA; other corpora may carry a court name). Read the value from the `court` field of case-law rows returned without the filter before filtering. Applies to case-law evidence only, which premium+ fan-out adds inside `search`; primary-law provisions have no court and are unaffected. A value that matches no case-law row is disclosed in meta.message, never served as a silent empty. Refused on tiers without case-law fan-out."New value: +"Exact-match filter on the issuing court of case-law rows: the corpus's own `court` value exactly as its case-law rows carry it (Dutch courts are codes such as HR, RVS, CRVB, CBB, GHAMS, RBDHA; other corpora may carry a court name). Read the value from the `court` field of case-law rows returned without the filter before filtering. Applies to case-law evidence only, which premium+ fan-out adds inside `search`; primary-law provisions have no court and are unaffected. A value that matches no case-law row is disclosed in meta.message, never served as a silent empty. A value that is not a court of any case-law source searched (and matched no row) refuses with isError=true and the unresolved_scope body: corrections[0] carries close court values and each source's court list. One court per call. Refused on tiers without case-law fan-out."
    • changedInput schema / properties / query / description
      Previous value: -"Search terms, matched with FTS5 implicit AND against each resolved corpus. Pass one or two canonical concept terms in the corpus language (SE: konsumentskydd, DE: Datenschutz), never a multi-concept compound. A bare uppercase OR between 2-3 terms is honoured as a disjunction (either term matches); other uppercase FTS operators (AND, NOT, NEAR) are stripped, not honoured. At most 500 characters: a longer query (a pasted case description, say) is refused before any source is searched, with isError=true and structuredContent error='validation_error', code='query_too_long'. Split the matter into separate issue queries of 2-5 legal terms, one call per issue, and merge the results."New value: +"Search terms, matched with FTS5 implicit AND against each resolved corpus. Pass one or two canonical concept terms in the corpus language (SE: konsumentskydd, DE: Datenschutz), never a multi-concept compound. A bare uppercase OR between 2-3 terms is honoured as a disjunction (either term matches); other uppercase FTS operators (AND, NOT, NEAR) are stripped, not honoured. At most 500 characters: a longer query (a pasted case description, say) is refused before any source is searched, with isError=true and structuredContent error='validation_error', code='query_too_long'. Split the matter into separate issue queries of 2-5 legal terms, one call per issue, and merge the results. A court-decision identifier in the query (an ECLI; in Dutch scope a capitalised LJN) is looked up exactly on premium+: meta.identifier_resolution lists each one with status resolved, not_found or failed and the source ids searched. On not_found, meta.message says the decision is not in Ansvar, and rows that only cite it carry match_mode='cites_identifier' (not a strict answer)."
  3. Changed1 schema field changed
    • addedInput schema / properties / workflow_id
      Added value: +{
      +  "description": "Id of the caller's own active included workflow run (Free and Solo), when this search is part of that run. Searches that name the run draw from its own allowance of 300 searches instead of the daily search budget, so a run is not cut off by the daily limit. At the run allowance the search is refused with cap='run_search_allowance'; it does not spill onto the daily budget. An id the gateway cannot verify as an active run you started (unknown, ended, or another account's) is not an error: the daily budget applies. Ignored on Premium, Team and Company, whose daily budgets a run does not reach. Does not change what is searched.",
      +  "title": "Workflow Id",
      +  "type": "string"
      +}
  4. Changed1 schema field changed
    • changedInput schema / properties / query / description
      Previous value: -"Search terms, matched with FTS5 implicit AND against each resolved corpus. Pass one or two canonical concept terms in the corpus language (SE: konsumentskydd, DE: Datenschutz), never a multi-concept compound. A bare uppercase OR between 2-3 terms is honoured as a disjunction (either term matches); other uppercase FTS operators (AND, NOT, NEAR) are stripped, not honoured."New value: +"Search terms, matched with FTS5 implicit AND against each resolved corpus. Pass one or two canonical concept terms in the corpus language (SE: konsumentskydd, DE: Datenschutz), never a multi-concept compound. A bare uppercase OR between 2-3 terms is honoured as a disjunction (either term matches); other uppercase FTS operators (AND, NOT, NEAR) are stripped, not honoured. At most 500 characters: a longer query (a pasted case description, say) is refused before any source is searched, with isError=true and structuredContent error='validation_error', code='query_too_long'. Split the matter into separate issue queries of 2-5 legal terms, one call per issue, and merge the results."
  5. Changed1 schema field changed
    • changedInput schema / properties / legal_areas / description
      Previous value: -"Publisher area-of-law ids, for the corpora that carry them; maximum 10. Ids are the publisher's own, case-sensitive (Rechtspraak: civielRecht, civielRecht_verbintenissenrecht; wetten.overheid.nl carries its own rechtsgebied ids), and a parent id also matches its sub-areas. Statute and regulation rows carry the area of the WHOLE act, so a hit is an article of an act classified in that area; court decisions carry the court's own area for each decision. The filter reaches legislation and case-law rows only — agency-guidance and preparatory-works rows are never area-filtered. A corpus that carries no area metadata serves its rows unfiltered; when at least one source applied the filter, unfiltered rows rank behind the filtered ones and fill at most two thirds of the window, so a filtered search can return fewer rows than limit (the count held out is in meta.search_scope.legal_areas_unfiltered_dropped). Every source that served unfiltered rows is named under meta.search_scope.legal_areas_not_applied with a reason (corpus_unclassified, no_envelope, not_forwarded), the sources that applied it under legal_areas_applied, and any id a corpus does not know under legal_areas_unknown_ids; a zero-row answer for a known id is a real answer. Legal order stays on jurisdictions=: legal_areas=['civielRecht'] with jurisdictions=['NL','EU'] filters the Dutch rows and keeps the EU rows, flagged unfiltered. No tier gate."New value: +"Publisher area-of-law ids, for the corpora that carry them; maximum 10. Ids are the publisher's own, case-sensitive (Rechtspraak: civielRecht, civielRecht_verbintenissenrecht; wetten.overheid.nl carries its own rechtsgebied ids), and a parent id also matches its sub-areas. Statute and regulation rows carry the area of the WHOLE act, so a hit is an article of an act classified in that area; court decisions carry the court's own area for each decision. The filter reaches legislation and case-law rows only — agency-guidance and preparatory-works rows are never area-filtered. A corpus that carries no area metadata serves its rows unfiltered; when at least one source applied the filter, unfiltered rows rank behind the filtered ones and fill at most two thirds of the window, so a filtered search can return fewer rows than limit (the count held out is in meta.search_scope.legal_areas_unfiltered_dropped). Every source that served unfiltered rows is named under meta.search_scope.legal_areas_not_applied with a reason (corpus_unclassified, no_envelope, not_forwarded), the sources that applied it under legal_areas_applied, and any id a corpus does not know under legal_areas_unknown_ids; a zero-row answer for a known id is a real answer. A source that knows NONE of the requested ids returns no rows under the filter: meta.message names it, and an empty answer carries recommended_action = 'CHECK_LEGAL_AREA_IDS' (drop legal_areas or add an id from that source's scheme). Legal order stays on jurisdictions=: legal_areas=['civielRecht'] with jurisdictions=['NL','EU'] filters the Dutch case-law rows and keeps the EU rows, flagged unfiltered. No tier gate."
  6. Changed1 schema field changed
    • changedInput schema / properties / legal_areas / description
      Previous value: -"Publisher area-of-law ids, for the corpora that carry them; maximum 10. Ids are the publisher's own, case-sensitive (Rechtspraak: civielRecht, civielRecht_verbintenissenrecht; wetten.overheid.nl carries its own rechtsgebied ids), and a parent id also matches its sub-areas. The filter reaches legislation and case-law rows only — agency-guidance and preparatory-works rows are never area-filtered. A corpus that carries no area metadata serves its rows unfiltered. Every source that served unfiltered rows is named under meta.search_scope.legal_areas_not_applied with a reason (corpus_unclassified, no_envelope, not_forwarded), the sources that applied it under legal_areas_applied, and any id a corpus does not know under legal_areas_unknown_ids; a zero-row answer for a known id is a real answer. Legal order stays on jurisdictions=: legal_areas=['civielRecht'] with jurisdictions=['NL','EU'] filters the Dutch rows and keeps the EU rows, flagged unfiltered. No tier gate."New value: +"Publisher area-of-law ids, for the corpora that carry them; maximum 10. Ids are the publisher's own, case-sensitive (Rechtspraak: civielRecht, civielRecht_verbintenissenrecht; wetten.overheid.nl carries its own rechtsgebied ids), and a parent id also matches its sub-areas. Statute and regulation rows carry the area of the WHOLE act, so a hit is an article of an act classified in that area; court decisions carry the court's own area for each decision. The filter reaches legislation and case-law rows only — agency-guidance and preparatory-works rows are never area-filtered. A corpus that carries no area metadata serves its rows unfiltered; when at least one source applied the filter, unfiltered rows rank behind the filtered ones and fill at most two thirds of the window, so a filtered search can return fewer rows than limit (the count held out is in meta.search_scope.legal_areas_unfiltered_dropped). Every source that served unfiltered rows is named under meta.search_scope.legal_areas_not_applied with a reason (corpus_unclassified, no_envelope, not_forwarded), the sources that applied it under legal_areas_applied, and any id a corpus does not know under legal_areas_unknown_ids; a zero-row answer for a known id is a real answer. Legal order stays on jurisdictions=: legal_areas=['civielRecht'] with jurisdictions=['NL','EU'] filters the Dutch rows and keeps the EU rows, flagged unfiltered. No tier gate."
  7. Changed1 schema field changed
    • addedInput schema / properties / legal_areas
      Added value: +{
      +  "description": "Publisher area-of-law ids, for the corpora that carry them; maximum 10. Ids are the publisher's own, case-sensitive (Rechtspraak: civielRecht, civielRecht_verbintenissenrecht; wetten.overheid.nl carries its own rechtsgebied ids), and a parent id also matches its sub-areas. The filter reaches legislation and case-law rows only — agency-guidance and preparatory-works rows are never area-filtered. A corpus that carries no area metadata serves its rows unfiltered. Every source that served unfiltered rows is named under meta.search_scope.legal_areas_not_applied with a reason (corpus_unclassified, no_envelope, not_forwarded), the sources that applied it under legal_areas_applied, and any id a corpus does not know under legal_areas_unknown_ids; a zero-row answer for a known id is a real answer. Legal order stays on jurisdictions=: legal_areas=['civielRecht'] with jurisdictions=['NL','EU'] filters the Dutch rows and keeps the EU rows, flagged unfiltered. No tier gate.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "title": "Legal Areas",
      +  "type": "array"
      +}
  8. Changed1 schema field changed
    • addedInput schema / properties / document_refs
      Added value: +{
      +  "description": "Exact edition keys from document discovery; 1–5 unique elx- keys with 24 lowercase hex digits. Accepted only with one sources entry advertising exact_document_filter and no jurisdictions, frameworks or sectors. Keys are OR-combined within that source.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "title": "Document Refs",
      +  "type": "array"
      +}
  9. Changed1 schema field changed
    • changedInput schema / properties / allow_broadening / description
      Previous value: -"Default false: a source that finds no strict match for the query is withheld instead of serving relaxed (OR-broadened) matches as if they were ordinary hits; the response names the withheld sources and count. Pass true to include those rows — each is stamped match_mode='broadened' — only after the user has accepted a broaden offer or asked for relaxed matches; never broaden unprompted. Relaxed rows pass the same on-topic relevance floor as strict rows, so an accepted re-run can still withhold them — disclosed in the response, never silently served."New value: +"Controlled-vocabulary term_bridge rows serve at the default, stamped match_mode='bridged'; meta.query_broadened_sources discloses requested_query, served_query and mode. Default false: a source that finds no strict match for the query is withheld instead of serving relaxed (OR-broadened) matches as if they were ordinary hits; the response names the withheld sources and count. Pass true to include those rows — each is stamped match_mode='broadened' — only after the user has accepted a broaden offer or asked for relaxed matches; never broaden unprompted. Relaxed rows pass the same on-topic relevance floor as strict rows, so an accepted re-run can still withhold them — disclosed in the response, never silently served."
  10. Changed3 schema fields changed
    • addedInput schema / properties / court
      Added value: +{
      +  "description": "Exact-match filter on the issuing court of case-law rows: the corpus's own `court` value exactly as its case-law rows carry it (Dutch courts are codes such as HR, RVS, CRVB, CBB, GHAMS, RBDHA; other corpora may carry a court name). Read the value from the `court` field of case-law rows returned without the filter before filtering. Applies to case-law evidence only, which premium+ fan-out adds inside `search`; primary-law provisions have no court and are unaffected. A value that matches no case-law row is disclosed in meta.message, never served as a silent empty. Refused on tiers without case-law fan-out.",
      +  "title": "Court",
      +  "type": "string"
      +}
    • addedInput schema / properties / date_from
      Added value: +{
      +  "description": "Inclusive lower bound as a full ISO date YYYY-MM-DD (a bare year such as 2023 is refused — pass 2023-01-01) on the decision date of case-law rows and the issue date of preparatory-work and agency-guidance rows. Premium+ evidence only; primary-law provisions carry no date and are unaffected.",
      +  "title": "Date From",
      +  "type": "string"
      +}
    • addedInput schema / properties / date_to
      Added value: +{
      +  "description": "Inclusive upper bound as a full ISO date YYYY-MM-DD on the decision date of case-law rows and the issue date of preparatory-work and agency-guidance rows; must not precede date_from. Premium+ evidence only; primary-law provisions are unaffected.",
      +  "title": "Date To",
      +  "type": "string"
      +}
  11. Changed1 schema field changed
    • changedInput schema / properties / allow_broadening / description
      Previous value: -"Default false: a source that finds no strict match for the query is withheld instead of serving relaxed (OR-broadened) matches as if they were ordinary hits; the response names the withheld sources and count. Pass true to include those rows — each is stamped match_mode='broadened' — only after the user has accepted a broaden offer or asked for relaxed matches; never broaden unprompted."New value: +"Default false: a source that finds no strict match for the query is withheld instead of serving relaxed (OR-broadened) matches as if they were ordinary hits; the response names the withheld sources and count. Pass true to include those rows — each is stamped match_mode='broadened' — only after the user has accepted a broaden offer or asked for relaxed matches; never broaden unprompted. Relaxed rows pass the same on-topic relevance floor as strict rows, so an accepted re-run can still withhold them — disclosed in the response, never silently served."
  12. Changed3 schema fields changed
    • changedInput schema / properties / frameworks / description
      Previous value: -"Registered framework scope ids such as GDPR or NIS2. Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query."New value: +"Registered framework scope ids such as GDPR or NIS2 — never a jurisdiction code (LI, DE, EU go in jurisdictions=). Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query."
    • changedInput schema / properties / jurisdictions / description
      Previous value: -"ISO-2 jurisdiction scope codes such as SE or EU; maximum 10. Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query."New value: +"ISO-2 jurisdiction scope codes such as SE or EU; maximum 10. A country code such as LI or DE belongs here and on no other axis. Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query."
    • changedInput schema / properties / sources / description
      Previous value: -"Exact corpus source ids such as eu-regulations or ietf-rfcs. Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query."New value: +"Exact corpus source ids such as eu-regulations or ietf-rfcs, read from describe_capabilities(section='sources') — never a hash, UUID, or document reference; a country code such as LI or DE belongs in jurisdictions=, not here. Pass at least one of jurisdictions, frameworks, sectors, or sources because search does not infer scope from the query."
  13. Changed1 schema field changed
    • changedInput schema / properties / allow_broadening / description
      Previous value: -"Default false: a source that finds no strict match for the query is withheld instead of serving relaxed (OR-broadened) matches as if they were ordinary hits; the response names the withheld sources and count. Pass true to include those rows — each is stamped match_mode='broadened'."New value: +"Default false: a source that finds no strict match for the query is withheld instead of serving relaxed (OR-broadened) matches as if they were ordinary hits; the response names the withheld sources and count. Pass true to include those rows — each is stamped match_mode='broadened' — only after the user has accepted a broaden offer or asked for relaxed matches; never broaden unprompted."
  14. Changed1 schema field changed
    • changedInput schema / properties / query / description
      Previous value: -"Search terms, matched with FTS5 implicit AND against each resolved corpus. Pass one or two canonical concept terms in the corpus language (SE: konsumentskydd, DE: Datenschutz), never a multi-concept compound. Uppercase FTS operators (AND, OR, NEAR) are stripped, not honoured — for alternatives, run one search per term."New value: +"Search terms, matched with FTS5 implicit AND against each resolved corpus. Pass one or two canonical concept terms in the corpus language (SE: konsumentskydd, DE: Datenschutz), never a multi-concept compound. A bare uppercase OR between 2-3 terms is honoured as a disjunction (either term matches); other uppercase FTS operators (AND, NOT, NEAR) are stripped, not honoured."
  15. Changed1 schema field changed
    • addedInput schema / properties / query / description
      Added value: +"Search terms, matched with FTS5 implicit AND against each resolved corpus. Pass one or two canonical concept terms in the corpus language (SE: konsumentskydd, DE: Datenschutz), never a multi-concept compound. Uppercase FTS operators (AND, OR, NEAR) are stripped, not honoured — for alternatives, run one search per term."
  16. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnly/openWorld=false/destructive=false, but the description adds a large amount of non-obvious behavior: daily budgets per tier, the run-allowance of 300 searches with refusal at cap='run_search_allowance', strict-miss meta.recovery fields, withheld relaxed matches with match_mode='broadened', the unresolved_scope refusal with isError=true, and the rule that broadening must never be done unprompted. It even discloses ranking policy (primary-lane window retention) that is unusual for a search tool.

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

Conciseness2/5

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

This is a single sprawling block of nearly 1,500 words with section labels wedged inline as ALL-CAPS clauses ('QUERY SHAPE:', 'TIER LIMITS:', 'RANKING:'), making it hard to scan for the one rule an agent needs mid-call. Several passages do not earn their place for tool selection: the primary-law window-fill ranking policy, meta.render_contract versioning, and the repeated quota arithmetic. The first two sentences are well front-loaded, but the rest is markedly over-written.

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

Completeness5/5

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

For a 14-parameter aggregating search with no output schema, the description covers what would otherwise be blind spots: which scope axes are required, how misses and partial fan-outs report through meta (including the trap that broadening_available=null means unknown, not 'no'), what to tell the user when results are zero, and that results should not be answered from training data. Nothing an agent needs in order to call this correctly or recover from a miss appears to be missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3; the description does add meaning beyond the schema in places, notably that jurisdictions+sectors is an INTERSECTION that errors when empty, that frameworks=['ISO_27001','SOC_2'] routes to Security Controls MCP, that court values should be read from unfiltered results first, and that a bare year is refused as date_from. However, much of the query-shape guidance (FTS5 implicit AND, uppercase OR honoured, 500-char limit, ECLI/LJN resolution) repeats the schema's own query description nearly verbatim, so it earns less credit than its volume suggests.

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

Purpose5/5

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

The opening states a specific verb and resource plus a hard precondition: 'Search requires at least one jurisdiction, framework, sector, or source; it does not auto-detect scope from the query.' It names its own distinct use cases ('what does the law say about X in country Y') and explicitly distinguishes itself from siblings by stating 'There is no separate search_case_law or search_preparatory_works tool; search_guidance can search guidance alone.'

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

Usage Guidelines5/5

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

When-to-use is explicit (two quoted question shapes), when-not is implied and then made concrete through the alternative tools: discover scope with list_coverage or describe_capabilities(section='sources'), fetch hits with get_provision, check quota with get_my_capabilities, use sources=['data-use-license'] for licences. The tier section tells the agent which capabilities are unavailable at free/solo/premium+, which prevents calling this tool for fan-out it cannot perform.

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.