# Courtlistener Citations Mcp

> MCP server for validating legal citations against CourtListener's 9M+ opinion database — detects AI-hallucinated citations, name mismatches, and ambiguous reporters with an interactive citation panel.

- **Type:** MCP server
- **Install:** `agentstack add mcp-john-walkoe-courtlistener-citations-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [john-walkoe](https://agentstack.voostack.com/s/john-walkoe)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [john-walkoe](https://github.com/john-walkoe)
- **Source:** https://github.com/john-walkoe/courtlistener_citations_mcp

## Install

```sh
agentstack add mcp-john-walkoe-courtlistener-citations-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# CourtListener Citation Validation MCP Server

A Model Context Protocol (MCP) server for validating legal citations against the [CourtListener](https://www.courtlistener.com/) database. Its primary use case is detecting AI-generated **hallucinated citations** in legal briefs and documents. Uses a local [eyecite](https://github.com/freelawproject/eyecite) pass to inventory all citation types first, then a 3-tool fallback chain against the CourtListener API for case citation validation.

[]()
[]()
[]()
[](LICENSE)

## 📚 Documentation

| Document | Description |
|----------|-------------|
| **[📥 Installation Guide](INSTALL.md)** | Complete cross-platform setup with automated scripts |
| **[📖 Usage Examples](USAGE_EXAMPLES.md)** | Workflows, fallback chain examples, and cross-MCP integration patterns |
| **[🎯 Prompt Templates](PROMPTS.md)** | Ready-to-use prompt templates for brief audits, hallucination triage, and pre-filing checklists |
| **[🛡️ Security Scanning](SECURITY_SCANNING.md)** | Automated secret detection and prompt injection protection guide |
| **[🏢 Enterprise Gateway Deployment](MCP_GATEWAY.md)** | Multi-user deployment via Bifrost, Azure APIM, or Microsoft MCP Gateway — per-user API keys, Entra ID SSO, bulk provisioning |
| **[⚖️ License](LICENSE)** | MIT License terms and conditions |

## Demo

Citation validation of *Mata v. Avianca*.  The MCP detects which citations are real, which are fabricated, and which resolve to the wrong case entirely.

https://github.com/user-attachments/assets/d1ba1b95-4bfe-4749-8ae7-a1255946e949

## Quick Start

### Docker (HTTP Mode)

**Prerequisites:** [Docker Desktop](https://www.docker.com/products/docker-desktop/) (or Docker Engine)

```bash
# 1. Clone the repo
git clone https://github.com/john-walkoe/courtlistener_citations_mcp.git
cd courtlistener_citations_mcp

# 2. Create a .env file with your CourtListener API token
#    (free token at https://www.courtlistener.com/sign-in/)
echo COURTLISTENER_API_TOKEN=your_40_char_hex_token_here > .env

# 3. Start the server
docker compose up -d

# Verify it's running
curl http://localhost:8000/health
```

**Claude Desktop config** (`%APPDATA%\Claude\claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "courtlistener_citations": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:8000/mcp"]
    }
  }
}
```

> The `.env` file is gitignored. Never commit it. See `.env.example` for reference.

---

### Windows STDIO Install

> **Note:** STDIO mode is fully supported, including the **interactive MCP App panel** — color-coded citation cards render inline in Claude Desktop without Docker. DPAPI/Credential Manager secure token storage is Windows STDIO only.

**Run PowerShell as Administrator**, then:

```powershell
# Navigate to your user profile
cd $env:USERPROFILE

# If git is installed:
git clone https://github.com/john-walkoe/courtlistener_citations_mcp.git
cd courtlistener_citations_mcp

# If git is NOT installed:
# Download and extract the repository to C:\Users\YOUR_USERNAME\courtlistener_citations_mcp
# Then navigate to the folder:
# cd C:\Users\YOUR_USERNAME\courtlistener_citations_mcp

# The script detects if uv is installed and if it is not it will install uv - https://docs.astral.sh/uv

# Run setup script (sets execution policy for this session only):
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process
.\deploy\windows_setup.ps1
```

The PowerShell script will:

- Check for and auto-install uv (via winget or PowerShell script)
- Install dependencies and create virtual environment
- Prompt for CourtListener API token (free at [courtlistener.com/sign-in](https://www.courtlistener.com/sign-in/))
- Store API token securely using Windows DPAPI encryption
- Ask to choose transport mode (STDIO or HTTP)
- Ask if you want Claude Desktop integration configured
- Offer secure configuration method (recommended) or traditional method (token in plain text in the MCP JSON file)
- Backup and automatically merge with existing Claude Desktop config (preserves other MCP servers)
- Provide installation summary and next steps

### Claude Desktop Configuration - Manual Install

**STDIO mode** (no MCP App panel in Claude Desktop — text results only):

```json
{
  "mcpServers": {
    "courtlistener_citations": {
      "command": "uv",
      "args": [
        "--directory",
        "C:/Users/YOUR_USERNAME/courtlistener_citations_mcp",
        "run",
        "courtlistener-mcp"
      ],
      "env": {
        "COURTLISTENER_API_TOKEN": "your_40_char_hex_token_here"
      }
    }
  }
}
```

**HTTP mode (via mcp-remote):**

```json
{
  "mcpServers": {
    "courtlistener_citations": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:8000/mcp/"
      ]
    }
  }
}
```

> **Note:** When using secure storage (Windows), the `env` block can be omitted entirely - the token is loaded automatically from Windows Credential Manager (or the DPAPI-encrypted file fallback) at runtime.

**Claude Code — Docker/HTTP mode (via mcp-remote, no dev tunnel):**

Add to `.claude.json` in your project root or `~/.claude.json` globally:

```json
{
  "mcpServers": {
    "courtlistener_citations": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:8000/mcp"
      ]
    }
  }
}
```

> Requires the Docker container to be running (`docker compose up -d`) and the `.env` file to contain `COURTLISTENER_API_TOKEN`. No token is needed in the JSON config itself — the container handles auth internally.

## Key Features

- **Local Citation Extraction** - [eyecite](https://github.com/freelawproject/eyecite) library inventories all citation types (case, statute, law journal, id., supra) locally before any API call — no API key, no rate limits, instant
- **Citation Validation** - 7-tool workflow detects hallucinated citations: local discovery first, then 3-tool fallback chain against CourtListener API
- **Dual Transport** - STDIO (Claude Desktop/Code) and Streamable HTTP (Docker, CoPilot Studio, remote clients)
- **MCP Apps UI** - Interactive citation validation results panel with color-coded cards and CourtListener links. Works in both STDIO (Claude Desktop direct) and HTTP/Docker mode.
- **Secure API Key Storage** - Windows DPAPI encryption for API tokens (no plain text in config files)
- **Elicitation Support** - Prompts for API token at runtime if not configured (FastMCP 3.0)
- **Tool Search Optimization** - Server instructions guide Claude to efficiently discover tools on-demand
- **SafeLogger with Auto-Sanitization** - Automatically masks API tokens, passwords, and sensitive data in all log messages
- **File-Based Logging with Rotation** - Persistent audit trail with 10MB rotation in `~/.courtlistener_citations_mcp/logs/`
- **Rate Limiting** - Dual token-bucket limiters: 83 req/min general (≤5,000/hr), 60 valid-citations/min for citation-lookup; automatic `wait_until` parsing on 429 responses
- **Multi-Tenant / Enterprise Ready** - Per-user client pool (LRU, 1000 entries) keyed by API token; each user gets their own rate limiter; shared circuit breaker reflects CourtListener API health globally. Accepts tokens via `Authorization: Bearer` (self-hosted) or `X-CourtListener-Token` (gateway-injected). See [MCP_GATEWAY.md](MCP_GATEWAY.md) for Bifrost/APIM deployment.
- **Cross-Platform** - Works on Linux and Windows (DPAPI on Windows, env var fallback on Linux)

### Workflow Design

**User requests:**

- *"Check if these citations in my brief are real"*
- *"Validate the citations in this legal document"*
- *"Look up Alice Corp v. CLS Bank and verify its citation"*
- *"Find Supreme Court cases about patent eligibility from 2014"*

**LLM performs the 4-step workflow:**

**Step 0: courtlistener_extract_citations (DISCOVERY)** - Runs eyecite locally to inventory ALL citation types in the document — case, statutory, law journal, id., supra. Free (no API), instant, no rate limits.

**Step 1: courtlistener_validate_citations (PRIMARY)** - Validate all case citations against CourtListener API using the eyecite parser

**Step 2: courtlistener_search_cases (FALLBACK)** - For any citations returning 404, search by case name to verify the case exists

**Step 3: courtlistener_lookup_citation (LAST RESORT)** - Direct reporter citation lookup when other methods fail

## Available Tools (7)

### Citation Discovery Tool (Local — No API)

| Tool | Purpose | Use Case |
|------|---------|----------|
| `courtlistener_extract_citations` | Extract all citation types locally via eyecite | **STEP 0** - Full census before API calls; identifies case, statute, journal, id., supra |

### Citation Validation Tools (3-Tool Fallback Chain)

| Tool | Purpose | Use Case |
|------|---------|----------|
| `courtlistener_validate_citations` | Extract & validate all case citations from text | **PRIMARY** - Paste full document text |
| `courtlistener_search_cases` | Search by case name, court, date, query | **FALLBACK** - When citation returns 404 |
| `courtlistener_lookup_citation` | Direct reporter citation lookup | **LAST RESORT** - Direct citation search |

### Supporting Tools

| Tool | Purpose | Use Case |
|------|---------|----------|
| `courtlistener_get_cluster` | Get full case details and CourtListener URLs | Deep dive into a specific case |
| `courtlistener_search_clusters` | Search opinion clusters with filters | Filtered search by judge, court, docket |
| `courtlistener_citations_get_guidance` | Workflow guidance and documentation (no API call) | Help with workflows and risk assessment |

### Tool Search Optimization (Claude Code v2.1.7+)

This MCP supports Claude Code's built-in tool search optimization, reducing context window usage through dynamic tool discovery.

**Always-Available Tools** (loaded immediately — non-deferred):
1. `courtlistener_validate_citations` - Primary citation validation
2. `courtlistener_citations_get_guidance` - Workflow guidance and documentation

**Discovered On-Demand** (deferred — searched via BM25):
3. `courtlistener_extract_citations` - Local citation discovery (eyecite, no API)
4. `courtlistener_search_cases` - Fallback search by case name
5. `courtlistener_get_cluster` - Case details and CourtListener URLs
6. `courtlistener_search_clusters` - Filtered cluster search
7. `courtlistener_lookup_citation` - Direct citation lookup

### Guidance Sections

Use `courtlistener_citations_get_guidance(section)` with these sections:

| Section | When to Use |
|---------|-------------|
| `overview` | What this MCP does and quick-start workflow |
| `workflow` | Full discovery + 3-tool fallback chain explained |
| `response_format` | How to format results with ✅⚠️❌ symbols |
| `hallucination_patterns` | Common AI hallucination detection patterns |
| `edge_cases` | SCOTUS parallel citations, state courts, unpublished opinions |
| `risk_assessment` | How to interpret validation results |
| `limitations` | CourtListener coverage gaps and false negatives |

## Transport Modes

| Mode | Use Case | MCP App Panel | Auth / Token Storage | Configuration |
|------|----------|--------------|----------------------|---------------|
| **STDIO** | Claude Desktop, Claude Code (single user) | ✅ Full panel | Windows Credential Manager + DPAPI (Windows) or env var | Default |
| **HTTP (Docker/direct)** | CoPilot Studio, web clients, single-host remote | ✅ Full panel | `COURTLISTENER_API_TOKEN` in `.env` or `Authorization: Bearer` header | `TRANSPORT=http` |
| **HTTP (Gateway)** | Law firm / enterprise, multi-user, Entra ID SSO | ❌ Panel not rendered through proxy | Per-user via `X-CourtListener-Token` injected by gateway (Bifrost, APIM) | See [MCP_GATEWAY.md](MCP_GATEWAY.md) |

> **MCP App panel** renders interactive color-coded citation cards inline in Claude Desktop. Works in STDIO and direct HTTP mode. Does not render when proxied through any gateway — but the tool's structured output and prompt engineering guide the LLM to produce an equivalent in-conversation report without the panel.

> **Per-user rate limiting:** In gateway deployments, each user's CourtListener API key gets its own 60-citation/min bucket. A shared circuit breaker reflects overall CourtListener API health without affecting per-user limits. See [MCP_GATEWAY.md](MCP_GATEWAY.md) for architecture details.

> **DPAPI / Windows Credential Manager** secure storage is only available in STDIO mode on Windows. Docker containers run Linux and cannot access Windows Credential Manager — use a `.env` file instead.

### Running in HTTP Mode

```bash
# Direct
set TRANSPORT=http
set PORT=8000
courtlistener-mcp

# Via uvicorn
uvicorn courtlistener_mcp.main:app --host 0.0.0.0 --port 8000

# Via Docker
docker compose up -d
# MCP endpoint: http://localhost:8000/mcp
# Health check: http://localhost:8000/health
```

#### Docker: API Token via .env file

Docker containers run Linux and cannot access Windows Credential Manager or DPAPI. The token **must** be provided via a `.env` file in the project root:

```bash
# .env (only this one variable is needed — TRANSPORT, HOST, PORT are hardcoded in docker-compose.yml)
COURTLISTENER_API_TOKEN=your_40_char_hex_token_here
```

> **Note:** The `.env` file is gitignored. Never commit it. The `.env.example` template is provided for reference.

### Dev Tunnel for CoPilot Studio / Claude.ai

> ⚠️ **Corporate & Regulatory Policy Notice**
>
> Dev tunnels create a **publicly accessible endpoint** for your local server. Before using this feature, you **must**:
>
> - **Consult your organization's IT security policy.** Many law firms, corporations, and government entities prohibit or restrict the use of development tunnels, reverse proxies, and other tools that bypass network perimeter controls on managed devices or corporate networks.
> - **Check your bar association's ethics rules.** Attorney obligations regarding client data confidentiality (Model Rules 1.6, 1.15) may impose additional constraints on transmitting client documents through third-party relay infrastructure.
> - **Do not use this feature on managed/corporate hardware** without explicit written approval from your IT/security team.
> - **Do not use this feature for production deployments.** Dev tunnels are intended for development and testing only. For production external access, use a properly secured reverse proxy (e.g., nginx with TLS) or a cloud-hosted deployment.
>
> If in doubt, ask your IT department first.

For external access (CoPilot Studio, Claude.ai), use the dev tunnel launcher script. It starts the HTTP server locally and creates a [Microsoft Dev Tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/) to expose it publicly.

**Prerequisites:** `devtunnel.exe` ([download](https://aka.ms/devtunnels)) and `devtunnel user login`

```powershell
# Temporary tunnel (URL changes each time)
.\deploy\start_devtunnel.ps1

# Custom port
.\deploy\start_devtunnel.ps1 -Port 8889

# Persistent tunnel (URL stays the same across restarts)
.\deploy\start_devtunnel.ps1 -Persistent
```

The script will:
- Ask whether the server is running in Docker or local Python
- Ask which port (defaults to 8000)
- Verify Docker container health (Docker mode) or start Python server (local mode)
- Auto-download `devtunnel.exe` if not found, and add Windows Firewall rules automatically (requires Admin)
- Create a dev tunnel with anonymous access
- Display the public MCP endpoint URL (`https://.devtunnels.ms/mcp`)
- On Ctrl+C: clean up the tunnel; leave Docker running (or stop the Python process)

Use the displayed tunnel URL as your MCP endpoint in CoPilot Studio or Claude.ai.

#### Example: Working Script Output (Docker mode)

```
=== CourtListener MCP - Dev Tunnel Launcher ===

[OK] devtunnel: C:\Users\...\courtlistener_citations_mcp\devtunnel.exe
[OK] Firewall rule exists for devtunnel.exe
[OK] Logged in as john@walkoe.com using Microsoft.
How is the MCP server running?
  [1] Docker (already running via 'docker compose up -d

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [john-walkoe](https://github.com/john-walkoe)
- **Source:** [john-walkoe/courtlistener_citations_mcp](https://github.com/john-walkoe/courtlistener_citations_mcp)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-john-walkoe-courtlistener-citations-mcp
- Seller: https://agentstack.voostack.com/s/john-walkoe
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
