search_opinions
Pack: court-listener · Endpoint: https://gateway.pipeworx.io/court-listener/mcp
Search US court opinions from CourtListener — 8.3 million of them, with no API key and no rate limit. Covers the UNITED STATES SUPREME COURT (SCOTUS), the federal circuit courts of appeals, the federal district courts, and the state courts (71% of the corpus is state case law). THE tool for what a US court HELD, decided or ruled in a NAMED CASE — “What did the Supreme Court hold in Air France v. Saks?”, “Miranda v. Arizona”, “the Ninth Circuit ruling in …” — including the treaty and statutory questions such cases turn on (Warsaw Convention, ERISA, the Fourth Amendment). Matches the case name, the judge, and (where CourtListener recorded one) a nature-of-suit/disposition category, so it is strongest on party names, judges, and case categories (“workers compensation”, “habeas”, “immigration”) and weaker on a legal DOCTRINE that would not appear in those fields (e.g. “qualified immunity”) — use find_case when you know the party, and expect this to sometimes miss on doctrine-only phrasing. Filter by jurisdiction (state vs federal, inferred from the citation reporter) and by date_filed (the real ruling date). A specific court code (e.g. “scotus”, “ca9”) or a filing after the covered window falls back to a live, token-less CourtListener search automatically. Every result carries snapshot_date and opinion_ids to read with get_opinion.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
query | string | yes | Search keywords — strongest on party names, judges and case categories (e.g. “workers compensation”, “Sotomayor”). |
jurisdiction | string | no | Filter to state or federal case law (inferred from the reporter citation). |
court | string | no | A specific court code (e.g. “scotus”, “ca9”, “nysd”). Not available on the indexed search — supplying this falls back to a live CourtListener search. |
date_after | string | no | Only opinions with a real filing date (date_filed) on or after this date (YYYY-MM-DD). |
date_before | string | no | Only opinions with a real filing date (date_filed) on or before this date (YYYY-MM-DD). |
limit | number | no | How many cases to return, 1–100 (default 10). |
Example call
Arguments
{
"query": "Air France v. Saks"
}
curl
curl -X POST https://gateway.pipeworx.io/court-listener/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_opinions","arguments":{"query":"Air France v. Saks"}}}'
TypeScript (@pipeworx/sdk)
import { Pipeworx } from '@pipeworx/sdk';
const pipeworx = new Pipeworx();
const result = await pipeworx.call('search_opinions', {
"query": "Air France v. Saks"
});
More examples
{
"query": "qualified immunity Fourth Amendment"
}
{
"query": "patent infringement software",
"court": "ca9",
"date_after": "2020-01-01"
}
Response shape
Always returns: query, returned, cases, source
| Field | Type | Description |
|---|---|---|
query | string | The search query used |
jurisdiction | string | null | state or federal when a jurisdiction filter applied, else null |
court | string | null | The court code requested, if any |
total | number | null | Full match count on the live path; null on the mirror path, which does not count total matches |
returned | number | Number of cases in this response |
truncated | boolean | null | True when more matches likely exist than were returned |
found | boolean | null | false only when nothing matched |
cases | array | Matching cases from CourtListener |
source | string | court-listener (mirror) or court-listener-live |
snapshot_date | string | null | Mirror data as-of date; null on the live path |
note | string | null | |
hint | string | null | Recovery hint when nothing matched |
attribution | string | null |
Full JSON Schema
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query used"
},
"jurisdiction": {
"type": [
"string",
"null"
],
"description": "state or federal when a jurisdiction filter applied, else null"
},
"court": {
"type": [
"string",
"null"
],
"description": "The court code requested, if any"
},
"total": {
"type": [
"number",
"null"
],
"description": "Full match count on the live path; null on the mirror path, which does not count total matches"
},
"returned": {
"type": "number",
"description": "Number of cases in this response"
},
"truncated": {
"type": [
"boolean",
"null"
],
"description": "True when more matches likely exist than were returned"
},
"found": {
"type": [
"boolean",
"null"
],
"description": "false only when nothing matched"
},
"cases": {
"type": "array",
"description": "Matching cases from CourtListener",
"items": {
"type": "object",
"properties": {
"cluster_id": {
"type": [
"number",
"null"
],
"description": "Case (cluster) id"
},
"docket_id": {
"type": [
"number",
"null"
],
"description": "Docket id"
},
"case_name": {
"type": [
"string",
"null"
],
"description": "Case name"
},
"case_name_full": {
"type": [
"string",
"null"
],
"description": "Full case name (mirror path; null on live)"
},
"date_filed": {
"type": [
"string",
"null"
],
"description": "Real filing date of the ruling"
},
"judges": {
"type": [
"string",
"null"
],
"description": "Judges recorded for the case"
},
"precedential_status": {
"type": [
"string",
"null"
],
"description": "Precedential status (e.g. Published)"
},
"citation_count": {
"type": [
"number",
"null"
],
"description": "How often later courts cited this case"
},
"citations": {
"type": "array",
"items": {
"type": "string"
},
"description": "Reporter citations, e.g. 470 U.S. 392"
},
"disposition": {
"type": [
"string",
"null"
],
"description": "Recorded disposition (thin coverage; null on live)"
},
"opinion_id": {
"type": [
"number",
"null"
],
"description": "Lead opinion id for get_opinion"
},
"opinion_ids": {
"type": "array",
"items": {
"type": "number"
},
"description": "All opinion ids (majority, concurrences, dissents)"
},
"excerpt": {
"type": [
"string",
"null"
],
"description": "Lead-opinion passages (opening + holding language + query match) — present on the most-cited case only; full text via get_opinion"
},
"url": {
"type": [
"string",
"null"
],
"description": "URL to the opinion on courtlistener.com"
},
"read_with": {
"type": [
"string",
"null"
],
"description": "The follow-up call that reads this case's full text"
}
}
}
},
"source": {
"type": "string",
"description": "court-listener (mirror) or court-listener-live"
},
"snapshot_date": {
"type": [
"string",
"null"
],
"description": "Mirror data as-of date; null on the live path"
},
"note": {
"type": [
"string",
"null"
]
},
"hint": {
"type": [
"string",
"null"
],
"description": "Recovery hint when nothing matched"
},
"attribution": {
"type": [
"string",
"null"
]
}
},
"required": [
"query",
"returned",
"cases",
"source"
]
}
Connect
Add this to your MCP client config, or use one-click install buttons:
{
"mcpServers": {
"court-listener": {
"url": "https://gateway.pipeworx.io/court-listener/mcp"
}
}
}
See Getting Started for client-specific install steps.