# CourtListener MCP Server

An MCP (Model Context Protocol) server providing AI agents access to [CourtListener's](https://www.courtlistener.com/) comprehensive legal database, featuring semantic search, hybrid search, citation verification, and research tools.

Intended for use with OpenCode and Claude Code via local system storage and runtime. Vibe-coded with Claude Code.

## Why This Project?

This MCP server is the **first to implement CourtListener's semantic search API** (released November 2025), enabling natural language legal research with vector embeddings. While other MCP servers exist for CourtListener, they all use traditional keyword-only search.

**Key Advantages:**
- **Semantic Search**: Natural language queries using legal domain embeddings
- **Hybrid Search**: Combines semantic understanding with required keywords
- **Citation Verification**: Validates legal citations to prevent AI hallucinations
- **Comprehensive Coverage**: 12 tools covering 9+ million cases, 16,000+ judges, 3,353 courts
- **Production Ready**: Built with proper error handling, rate limiting, and async operations

**Mission**: Developed by [DefendTheDisabled](https://github.com/DefendTheDisabled) to support civil rights litigation and make legal research more accessible through AI-powered tools.

## Features

### Search Capabilities
- **Semantic Search**: Natural language case law search using CourtListener's vector embeddings
- **Keyword Search**: Boolean operators, fielded queries, and wildcards (AND, OR, NOT, phrases)
- **Hybrid Search**: Combine semantic understanding with required keywords for precision
- **Citation Verification**: Validate legal citations against 18+ million case records

### Research Tools
- **Case Retrieval**: Full case metadata, opinion text, and docket information
- **Judge Database**: Search 16,000+ federal and state judges with biographical data
- **Oral Arguments**: Access 3.3+ million minutes of oral argument recordings
- **Court Information**: Browse and search 3,353 courts across all jurisdictions

## Requirements

- Python 3.10 or higher (3.12 recommended)
- CourtListener API key ([get one free here](https://www.courtlistener.com/help/api/rest/))
- An MCP-compatible client (tested with Claude Code and OpenCode)

## Installation

### Quick Start

```bash
# Clone the repository
git clone https://github.com/DefendTheDisabled/courtlistener-mcp.git
cd courtlistener-mcp

# Install dependencies
pip install -e .
```

### Configuration

1. Copy the example environment file:
   ```bash
   cp .env.example .env
   ```

2. Edit `.env` and add your CourtListener API key:
   ```env
   COURTLISTENER_API_KEY=your_api_token_here
   ```

   Get your free API key at: https://www.courtlistener.com/help/api/rest/

## Usage

This server currently supports **STDIO transport** for local MCP clients. Future versions may include HTTP transport for remote access by web-based AI platforms.

### OpenCode

**Using CLI (Recommended):**

```bash
opencode mcp add
```

Follow the prompts:
- Server name: `courtlistener`
- Type: `local`
- Command: `python`
- Args: `/absolute/path/to/courtlistener-mcp/src/server.py`

**Manual Configuration:**

Add to your OpenCode config (`~/.config/opencode/opencode.json` for global, or `opencode.json` in project root):

```json
{
  "mcp": {
    "courtlistener": {
      "type": "local",
      "command": ["python", "/absolute/path/to/courtlistener-mcp/src/server.py"],
      "enabled": true
    }
  }
}
```

**Notes:**
- Use absolute paths (e.g., `C:/Users/YourName/MCP/courtlistener/src/server.py` on Windows)
- You can install to any directory you choose
- The `.env` file in the server directory will be auto-loaded
- See [OpenCode MCP documentation](https://opencode.ai/docs/mcp-servers/) for more details

### Claude Code

**Using CLI:**

```bash
claude mcp add courtlistener python /absolute/path/to/courtlistener-mcp/src/server.py
```

**Manual Configuration:**

Edit `~/.claude/settings.json`:

```json
{
  "mcpServers": {
    "courtlistener": {
      "command": "python",
      "args": ["/absolute/path/to/courtlistener-mcp/src/server.py"]
    }
  }
}
```

**Notes:**
- Use absolute paths
- The `.env` file in the server directory will be auto-loaded

### Other MCP Clients

This server uses STDIO transport and follows the [MCP specification](https://spec.modelcontextprotocol.io/).

**Current limitation**: Local clients only (runs as a child process on your system).

**Future plans**: We plan to develop an HTTP transport version that can be accessed remotely by web-based AI platforms (Claude web, ChatGPT, etc.) while maintaining security and proper authentication.

## Available Tools

### Search Tools (4)

| Tool | Description | Use Case |
|------|-------------|----------|
| `courtlistener_search_cases_semantic` | Natural language case search | "Find cases about prisoners denied medical care" |
| `courtlistener_search_cases_keyword` | Boolean/fielded search | `"deliberate indifference" AND prison` |
| `courtlistener_search_cases_hybrid` | Semantic + required keywords | Best of both: context + precision |
| `courtlistener_verify_citation` | Validate citations | Verify "429 U.S. 97" exists and get details |

### Retrieval Tools (4)

| Tool | Description |
|------|-------------|
| `courtlistener_get_case` | Get full case metadata by cluster ID |
| `courtlistener_get_opinion` | Get complete opinion text with citations |
| `courtlistener_get_docket` | Get docket information and filing history |
| `courtlistener_get_citing_cases` | Find all cases that cite a specific opinion |

### Research Tools (4)

| Tool | Description |
|------|-------------|
| `courtlistener_search_judges` | Search judges by name, court, or appointment info |
| `courtlistener_search_oral_arguments` | Find oral argument recordings by case |
| `courtlistener_list_courts` | List all courts in the database |
| `courtlistener_get_court_info` | Get detailed information about a specific court |

**Total: 12 tools** providing comprehensive access to CourtListener's legal database.

## Example Queries

### Semantic Search (Natural Language)

```
Query: "prisoners denied medical treatment for serious conditions"
```

Returns cases semantically related to Eighth Amendment deliberate indifference claims, even if they don't use those exact terms.

### Keyword Search (Boolean Operators)

```
Query: "deliberate indifference" AND prison AND medical
Court: ca9 (Ninth Circuit)
Date Range: 2020-2024
```

Precise Boolean search with field filtering for targeted research.

### Hybrid Search (Best of Both)

```
Query: "prison conditions and medical care violations"
Required Terms: ["Eighth Amendment", "deliberate indifference"]
```

Semantic understanding of context + guaranteed inclusion of specific legal terms.

### Citation Verification

```
Text: "In Estelle v. Gamble, 429 U.S. 97 (1976), the Court held..."
```

Validates the citation exists, returns full case metadata, and provides CourtListener URLs.

### Judge Research

```
Query: "Sotomayor"
```

Returns biographical data, appointment history, education, and political affiliation.

### Finding Citing Cases

```
Opinion ID: 109561 (Estelle v. Gamble)
```

Returns all subsequent cases that cite this opinion, essential for checking if a case is still good law.

## Rate Limits

CourtListener provides **5,000 API requests per hour** per authenticated user. The server handles rate limit errors gracefully and provides clear error messages.

## Response Formats

All tools support two output formats:
- **Markdown** (default): Human-readable format for conversational use
- **JSON**: Structured data for programmatic processing

Specify format with the `response_format` parameter.

## Troubleshooting

### "API key not found" error

Make sure your `.env` file is in the same directory as `server.py` and contains:
```env
COURTLISTENER_API_KEY=your_actual_key_here
```

### Server not loading in Claude Code

1. Check that you're using absolute paths in the MCP config
2. Verify Python is in your PATH: `python --version`
3. Test the server manually: `python /path/to/server.py`
4. Check Claude Code logs for startup errors

### "Rate limit exceeded" error

You've hit the 5,000 requests/hour limit. Wait an hour or use a different API key for testing.

### Slow startup times

If the server takes 30+ seconds to start:
- Disable antivirus scanning for your Python installation and project directory
- This is often caused by real-time malware scanning on Windows

### Citation not found

CourtListener has 18+ million citations but may not have very recent cases or unpublished opinions. Try:
- Checking the citation format (e.g., "429 U.S. 97" not "429 US 97")
- Using semantic search instead if you don't have a specific citation
- Verifying the case exists on [courtlistener.com](https://www.courtlistener.com/)

## Development

### Running Tests

```bash
# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/
```

### Code Formatting

```bash
# Format code
black src/

# Sort imports
isort src/
```

## Project Structure

```
courtlistener-mcp/
├── src/
│   ├── __init__.py
│   ├── server.py          # FastMCP server with tool registration
│   ├── config.py          # Environment configuration
│   └── api_client.py      # CourtListener API wrapper
├── tests/
│   └── __init__.py        # Test suite
├── .env.example           # Environment template
├── .gitignore
├── pyproject.toml         # Dependencies and metadata
├── README.md
└── LICENSE
```

## Technology Stack

- **MCP Framework**: [FastMCP](https://github.com/jlowin/fastmcp) 2.x
- **HTTP Client**: [httpx](https://www.python-httpx.org/) (async with connection pooling)
- **Validation**: [Pydantic](https://docs.pydantic.dev/) 2.x
- **Configuration**: [python-dotenv](https://github.com/theskumar/python-dotenv)

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

Areas where help is appreciated:
- Additional test coverage
- Performance optimizations
- Documentation improvements
- Bug reports and fixes

## License

MIT License - see [LICENSE](LICENSE) file for details.

## Acknowledgments

- [CourtListener](https://www.courtlistener.com/) and the [Free Law Project](https://free.law/) for providing free access to legal data
- [FastMCP](https://github.com/jlowin/fastmcp) framework by Marvin
- The MCP community for protocol development and tooling

## Related Projects

- [MCP Specification](https://spec.modelcontextprotocol.io/)
- [CourtListener API Documentation](https://www.courtlistener.com/help/api/)
- [Free Law Project](https://free.law/)

## Support

- **Issues**: Please report bugs and feature requests via [GitHub Issues](https://github.com/DefendTheDisabled/courtlistener-mcp/issues)
- **CourtListener API**: For API-related questions, see [CourtListener's help documentation](https://www.courtlistener.com/help/api/rest/)
- **MCP Protocol**: For MCP-specific questions, see the [MCP documentation](https://modelcontextprotocol.io/)
