@cyanheads/courtlistener-mcp-server

v0.1.4 pre-1.0

Search and retrieve US court opinions, federal dockets, judge records, citation networks, and oral arguments from CourtListener's 9M+ opinion corpus via MCP. STDIO or Streamable HTTP.

@cyanheads/courtlistener-mcp-server
claude mcp add --transport http courtlistener-mcp-server https://courtlistener.caseyjhand.com/mcp
codex mcp add courtlistener-mcp-server --url https://courtlistener.caseyjhand.com/mcp
{
  "mcpServers": {
    "courtlistener-mcp-server": {
      "url": "https://courtlistener.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http courtlistener-mcp-server https://courtlistener.caseyjhand.com/mcp
{
  "mcpServers": {
    "courtlistener-mcp-server": {
      "command": "bunx",
      "args": [
        "@cyanheads/courtlistener-mcp-server@latest"
      ]
    }
  }
}
{
  "mcpServers": {
    "courtlistener-mcp-server": {
      "type": "http",
      "url": "https://courtlistener.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://courtlistener.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

10

courtlistener_search_opinions

open-world

Full-text search across 9M+ written US court opinions with field-level filtering. Returns opinion cluster summaries with case metadata, citations, and matched text snippets. Supports CourtListener field syntax (caseName:"roe v wade", court_id:scotus, judge:"Alito") and boolean operators (AND, OR, NOT). Use courtlistener_lookup_courts to find court IDs. Rate limit: 5 req/min, 50/hr, 125/day on the free tier.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_search_opinions",
    "arguments": {
      "q": "<q>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "q": {
      "type": "string",
      "minLength": 1,
      "description": "Full-text query. Supports field syntax (caseName:\"roe v wade\", court_id:scotus, judge:\"Alito\") and boolean operators (AND, OR, NOT). Use plain English for semantic-style queries or legal citations."
    },
    "court": {
      "description": "Filter to a specific court by court ID (e.g., \"scotus\", \"ca9\", \"nyed\"). Use courtlistener_lookup_courts to find court IDs.",
      "type": "string"
    },
    "filed_after": {
      "description": "Earliest filing date (ISO 8601, e.g., \"2020-01-01\"). Narrows search to opinions filed on or after this date.",
      "type": "string"
    },
    "filed_before": {
      "description": "Latest filing date (ISO 8601). Narrows search to opinions filed before or on this date.",
      "type": "string"
    },
    "status": {
      "description": "Opinion publication status. \"Published\": precedential. \"Unpublished\": not citable as precedent in most jurisdictions. \"Errata\": corrections. \"Separate\": separate opinion filed outside main cluster. \"In-chambers\": single-justice order. \"Relating-to\": companion or related-case order. Omit to search all statuses.",
      "type": "string",
      "enum": [
        "Published",
        "Unpublished",
        "Errata",
        "Separate",
        "In-chambers",
        "Relating-to",
        "Unknown"
      ]
    },
    "order_by": {
      "default": "score desc",
      "description": "Result ordering. \"score desc\" (default) ranks by relevance. \"citeCount desc\" surfaces most-cited opinions first.",
      "type": "string",
      "enum": [
        "score desc",
        "dateFiled desc",
        "dateFiled asc",
        "citeCount desc"
      ]
    },
    "page_size": {
      "default": 20,
      "description": "Number of results to request (default 20). CourtListener search enforces a minimum of 20 results per page regardless of the value passed — you will always receive at least 20 results. Each search costs one request against the rate limit.",
      "type": "integer",
      "minimum": 1,
      "maximum": 20
    },
    "cursor": {
      "description": "Pagination cursor from a previous response's next_cursor field. Omit for the first page.",
      "type": "string"
    }
  },
  "required": [
    "q",
    "order_by",
    "page_size"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_get_opinion

Fetch the full text and metadata for a single opinion cluster by cluster ID. A cluster groups all opinions filed in a case — majority, concurrence, dissent, and per curiam. Returns all opinion variants with HTML and plain text. Obtain cluster IDs from courtlistener_search_opinions, courtlistener_lookup_citation, or docket results.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_get_opinion",
    "arguments": {
      "cluster_id": "<cluster_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "cluster_id": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991,
      "description": "Opinion cluster ID — identifies a case decision and groups all opinion variants (majority, concurrence, dissent). Obtain from courtlistener_search_opinions, courtlistener_lookup_citation, or from docket results that link to opinions."
    }
  },
  "required": [
    "cluster_id"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_get_citations

open-world

Retrieve the citation network for an opinion cluster. Supports two directions: "cited_by" (opinions that cite this one — measures precedential influence) and "citing" (opinions this one cites — reveals the authority chain relied on). This is the primary tool for tracing legal precedent chains. Note: the free tier (125 req/day) supports shallow traversal — following 1–2 hops of a single case is practical; deep multi-hop analysis burns through the daily budget quickly.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_get_citations",
    "arguments": {
      "cluster_id": "<cluster_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "cluster_id": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991,
      "description": "Opinion cluster ID to retrieve citations for. Obtain from courtlistener_search_opinions or courtlistener_lookup_citation."
    },
    "direction": {
      "default": "cited_by",
      "description": "\"cited_by\" (default): opinions that cite this one — measures precedential influence and downstream adoption. \"citing\": opinions this one cites — reveals the authority chain the court relied on.",
      "type": "string",
      "enum": [
        "citing",
        "cited_by"
      ]
    },
    "court": {
      "description": "Filter results to a specific court (e.g., \"scotus\", \"ca9\"). Applies to both directions.",
      "type": "string"
    },
    "filed_after": {
      "description": "Limit to citations filed after this date (ISO 8601). For \"cited_by\", useful for \"how has this precedent been applied recently?\"",
      "type": "string"
    },
    "page_size": {
      "default": 10,
      "description": "Number of results (1–20). Each citation tool call costs one request against the rate limit — keep page_size low for multi-hop traversal.",
      "type": "integer",
      "minimum": 1,
      "maximum": 20
    },
    "cursor": {
      "description": "Pagination cursor from a previous response's next_cursor field.",
      "type": "string"
    }
  },
  "required": [
    "cluster_id",
    "direction",
    "page_size"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_lookup_citation

Resolve a formatted legal citation string (e.g., "410 U.S. 113", "93 S. Ct. 705") to a cluster ID and case metadata. Enables workflows that start from a known citation rather than a search query. Supports standard US reporter formats. Requires authentication — uses the CourtListener /citation-lookup/ endpoint.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_lookup_citation",
    "arguments": {
      "citation": "<citation>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "citation": {
      "type": "string",
      "minLength": 1,
      "description": "Legal citation string to resolve (e.g., \"410 U.S. 113\", \"347 U.S. 483\", \"93 S. Ct. 705\"). Supports standard reporter formats."
    }
  },
  "required": [
    "citation"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_search_dockets

open-world

Search RECAP federal court dockets with party name, attorney, court, and date filters. RECAP is a crowd-sourced mirror of PACER (the federal court filing system) — coverage varies by court and date. Returns docket metadata with up to 3 sample document entries per docket. Use courtlistener_lookup_courts to find court IDs.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_search_dockets",
    "arguments": {
      "q": "<q>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "q": {
      "type": "string",
      "minLength": 1,
      "description": "Query terms matched against case name, docket number, party names, and attorney names. Example: \"Apple Inc patent infringement\"."
    },
    "court": {
      "description": "Filter to a specific federal court ID (e.g., \"dnd\", \"cacd\", \"deb\" for Delaware Bankruptcy). Use courtlistener_lookup_courts to find court IDs.",
      "type": "string"
    },
    "party_name": {
      "description": "Filter to dockets listing a specific party by name — applied in addition to (AND with) the q query. More precise than including party names in q when the party name is known.",
      "type": "string"
    },
    "filed_after": {
      "description": "Earliest case filing date (ISO 8601).",
      "type": "string"
    },
    "filed_before": {
      "description": "Latest case filing date (ISO 8601).",
      "type": "string"
    },
    "page_size": {
      "default": 20,
      "description": "Number of results to request (default 20). CourtListener search enforces a minimum of 20 results per page regardless of the value passed — you will always receive at least 20 results.",
      "type": "integer",
      "minimum": 1,
      "maximum": 20
    },
    "cursor": {
      "description": "Pagination cursor from a previous response's next_cursor field.",
      "type": "string"
    }
  },
  "required": [
    "q",
    "page_size"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_get_docket

Fetch full docket metadata and entry list for a single federal case by docket ID. Returns all available docket entries with document availability status. Documents with is_available=true have a RECAP-stored copy; others require a PACER account. Obtain docket IDs from courtlistener_search_dockets or from opinion results.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_get_docket",
    "arguments": {
      "docket_id": "<docket_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "docket_id": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991,
      "description": "Docket ID from a search result's docket_id field or from an opinion cluster result."
    },
    "entries_page_size": {
      "default": 20,
      "description": "Number of docket entries to return (1–50). Large cases can have hundreds of entries.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    }
  },
  "required": [
    "docket_id",
    "entries_page_size"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_search_judges

open-world

Search judge/person records by name, appointing president, court, political affiliation, or demographic. Returns biographical data, current position, and appointment summary. Use courtlistener_get_judge for full appointment history and education records.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_search_judges",
    "arguments": {
      "q": "<q>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "q": {
      "type": "string",
      "minLength": 1,
      "description": "Search query — judge name, court, city, or relevant keywords."
    },
    "appointer": {
      "description": "Filter by appointing president's last name (e.g., \"Obama\", \"Trump\", \"Biden\"). Matches against the appointer field in position records.",
      "type": "string"
    },
    "court": {
      "description": "Filter to judges who have held a position at this court (e.g., \"scotus\", \"ca9\"). Use court_id strings from courtlistener_lookup_courts.",
      "type": "string"
    },
    "political_affiliation": {
      "description": "Filter by political affiliation: d=Democrat, r=Republican, i=Independent, l=Libertarian, g=Green Party, u=Unknown/unconfirmed. Based on party of the appointing president or election affiliation.",
      "type": "string",
      "enum": [
        "d",
        "r",
        "i",
        "l",
        "g",
        "u"
      ]
    },
    "page_size": {
      "default": 20,
      "description": "Number of results to request (default 20). CourtListener search enforces a minimum of 20 results per page regardless of the value passed.",
      "type": "integer",
      "minimum": 1,
      "maximum": 20
    },
    "cursor": {
      "description": "Pagination cursor from a previous response's next_cursor field.",
      "type": "string"
    }
  },
  "required": [
    "q",
    "page_size"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_get_judge

Fetch full biographical profile for a single judge: appointment history across all courts, education, political affiliations, and ABA ratings. Obtain person IDs from courtlistener_search_judges results.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_get_judge",
    "arguments": {
      "person_id": "<person_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "person_id": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991,
      "description": "Judge person ID from a search result's person_id field. Identifies a specific judge across all courts they have served on."
    }
  },
  "required": [
    "person_id"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_lookup_courts

open-world

List courts with optional filtering by jurisdiction type and scraper status. Primarily used to discover court IDs for use in search and filter parameters across all other courtlistener tools. Returns court IDs, full names, citation strings, and scraper status.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_lookup_courts",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "jurisdiction": {
      "description": "Jurisdiction type. F=Federal Appellate (circuit courts, SCOTUS), FD=Federal District, FB=Federal Bankruptcy, FBP=Federal Bankruptcy Panel, FS=Federal Special (USITC, FISC, etc.), C=Circuit (historical), I=International, T=Territory, ST=State Trial, SS=State Supreme, SAG=State Attorney General, SAL=State Legislature, SA=State Appellate, S=State (other), TT=Tribal/Territory. Omit to list all.",
      "type": "string",
      "enum": [
        "F",
        "FD",
        "FB",
        "FBP",
        "FS",
        "C",
        "I",
        "T",
        "ST",
        "SS",
        "SAG",
        "SAL",
        "SA",
        "S",
        "TT"
      ]
    },
    "in_use": {
      "default": true,
      "description": "When true (default), only return courts currently scraped by CourtListener. Set to false to include historical or inactive courts.",
      "type": "boolean"
    },
    "has_opinion_scraper": {
      "description": "Filter to courts with active opinion scraping. Useful when planning search queries — courts without scrapers have sparse coverage.",
      "type": "boolean"
    }
  },
  "required": [
    "in_use"
  ],
  "additionalProperties": false
}
view source ↗

courtlistener_search_oral_arguments

open-world

Search appellate oral argument audio recordings — the largest public collection of oral argument audio. Returns recording metadata with download URLs, panel judge IDs, and transcript snippets where available. Download URLs are direct MP3 links. Panel judge IDs can be passed to courtlistener_get_judge for biographical context.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "courtlistener_search_oral_arguments",
    "arguments": {
      "q": "<q>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "q": {
      "type": "string",
      "minLength": 1,
      "description": "Query terms matched against case name and transcribed argument text (where available)."
    },
    "court": {
      "description": "Filter to a specific court (e.g., \"scotus\", \"ca9\").",
      "type": "string"
    },
    "argued_after": {
      "description": "Earliest date the case was argued (ISO 8601) — filters by argument date, not publication date.",
      "type": "string"
    },
    "argued_before": {
      "description": "Latest date the case was argued (ISO 8601).",
      "type": "string"
    },
    "page_size": {
      "default": 20,
      "description": "Number of results to request (default 20). CourtListener search enforces a minimum of 20 results per page regardless of the value passed.",
      "type": "integer",
      "minimum": 1,
      "maximum": 20
    },
    "cursor": {
      "description": "Pagination cursor from a previous response's next_cursor field.",
      "type": "string"
    }
  },
  "required": [
    "q",
    "page_size"
  ],
  "additionalProperties": false
}
view source ↗

Resources

1

Static reference guide for CourtListener court IDs, jurisdiction type codes, search type codes, and rate limit information. Read this before building queries to find the correct court ID and jurisdiction filter values.

uri courtlistener://reference/courts mime text/markdown

Prompts

1

Generate a structured legal research plan for a given legal topic or question. Produces a step-by-step workflow using CourtListener tools to find relevant case law, trace precedent chains, and surface key opinions.

  • topicrequired — Legal topic, question, or issue to research (e.g., "Fourth Amendment cell phone search", "Title VII hostile work environment", "Section 1983 qualified immunity").
  • jurisdiction — Optional jurisdiction to focus on (e.g., "scotus" for Supreme Court, "ca9" for Ninth Circuit, "nyed" for SDNY). Omit for nationwide research.
  • depth — "overview" (default): find 3–5 key cases. "deep": include citation network traversal and judge lookup. Note: deep research uses more of the 125 req/day free-tier budget.