CourtListener Citation Validation MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@CourtListener Citation Validation MCP ServerValidate these citations for hallucinations: 410 U.S. 113"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
CourtListener Citation Validation MCP Server
A Model Context Protocol (MCP) server for validating legal citations against the CourtListener database. Its primary use case is detecting AI-generated hallucinated citations in legal briefs and documents. Uses a local eyecite pass to inventory all citation types first, then a 3-tool fallback chain against the CourtListener API for case citation validation.
๐ Documentation
Document | Description |
Complete cross-platform setup with automated scripts | |
Workflows, fallback chain examples, and cross-MCP integration patterns | |
Ready-to-use prompt templates for brief audits, hallucination triage, and pre-filing checklists | |
Automated secret detection and prompt injection protection guide | |
Multi-user deployment via Bifrost, Azure APIM, or Microsoft MCP Gateway โ per-user API keys, Entra ID SSO, bulk provisioning | |
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 (or Docker Engine)
# 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/healthClaude Desktop config (%APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"courtlistener_citations": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:8000/mcp"]
}
}
}The
.envfile is gitignored. Never commit it. See.env.examplefor 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:
# 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.ps1The 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)
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):
{
"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):
{
"mcpServers": {
"courtlistener_citations": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:8000/mcp/"
]
}
}
}Note: When using secure storage (Windows), the
envblock 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:
{
"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.envfile to containCOURTLISTENER_API_TOKEN. No token is needed in the JSON config itself โ the container handles auth internally.
Key Features
Local Citation Extraction - 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_untilparsing on 429 responsesMulti-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) orX-CourtListener-Token(gateway-injected). See 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 |
| 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 |
| Extract & validate all case citations from text | PRIMARY - Paste full document text |
| Search by case name, court, date, query | FALLBACK - When citation returns 404 |
| Direct reporter citation lookup | LAST RESORT - Direct citation search |
Supporting Tools
Tool | Purpose | Use Case |
| Get full case details and CourtListener URLs | Deep dive into a specific case |
| Search opinion clusters with filters | Filtered search by judge, court, docket |
| 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):
courtlistener_validate_citations- Primary citation validationcourtlistener_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 |
| What this MCP does and quick-start workflow |
| Full discovery + 3-tool fallback chain explained |
| How to format results with โ โ ๏ธโ symbols |
| Common AI hallucination detection patterns |
| SCOTUS parallel citations, state courts, unpublished opinions |
| How to interpret validation results |
| 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 |
|
|
HTTP (Gateway) | Law firm / enterprise, multi-user, Entra ID SSO | โ Panel not rendered through proxy | Per-user via | See 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 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
.envfile instead.
Running in HTTP Mode
# 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/healthDocker: 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:
# .env (only this one variable is needed โ TRANSPORT, HOST, PORT are hardcoded in docker-compose.yml)
COURTLISTENER_API_TOKEN=your_40_char_hex_token_hereNote: The
.envfile is gitignored. Never commit it. The.env.exampletemplate 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 to expose it publicly.
Prerequisites: devtunnel.exe (download) and devtunnel user login
# 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 -PersistentThe 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.exeif not found, and add Windows Firewall rules automatically (requires Admin)Create a dev tunnel with anonymous access
Display the public MCP endpoint URL (
https://<tunnel>.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')
[2] Local Python (start it now via uv/venv)
Enter choice (1 or 2, default is 1): 1
Port the server is/will run on (default: 8000):
[INFO] Docker mode - checking container health on port 8000...
[OK] Docker container healthy at http://localhost:8000
Health: http://localhost:8000/health
MCP: http://localhost:8000/mcp
[INFO] Starting temporary dev tunnel on port 8000...
========================================
Tunnel is starting...
Look for the URL below (*.devtunnels.ms)
Your MCP endpoint will be:
<tunnel-url>/mcp
For CoPilot Studio or Claude.ai, use:
https://<tunnel-subdomain>.devtunnels.ms/mcp
Press Ctrl+C to stop tunnel and server
========================================
Hosting port: 8000
Connect via browser: https://3tgxrktm.usw3.devtunnels.ms:8000, https://3tgxrktm-8000.usw3.devtunnels.ms
Inspect network activity: https://3tgxrktm-8000-inspect.usw3.devtunnels.ms
Ready to accept connections for tunnel: quick-pond-mprv3rk.usw3MCP endpoint: https://3tgxrktm-8000.usw3.devtunnels.ms/mcp
Note: Temporary tunnel URLs change every run. Use
-Persistentfor a stable URL across restarts.
Firewall & Network: Lessons Learned
Getting devtunnel working on a hardened network required clearing multiple independent layers. If your tunnel fails with a connection timeout to global.rel.tunnels.api.visualstudio.com:443, work through this checklist:
1. Windows Firewall
The script automatically checks and adds outbound/inbound rules for devtunnel.exe. Run PowerShell as Administrator on the first run so it can create the rules. Verify with:
Get-NetFirewallApplicationFilter -Program "C:\path\to\devtunnel.exe"2. Pi-hole / DNS sinkhole If you run Pi-hole or similar DNS blocking, add these to your allowlist:
(\.|^)devtunnels\.ms$(\.|^)visualstudio\.com$(\.|^)microsoftonline\.com$(\.|^)live\.com$
3. Allow Outbound to Microsoft
The devtunnel relay uses Microsoft Azure US West IPs (20.125.0.0/16). If a firewall is blocking outbound traffic, add 20.125.0.0/16 to your Firewall's allow outbound list and Update.
5. Test connectivity before running the script
Test-NetConnection global.rel.tunnels.api.visualstudio.com -Port 443
# TcpTestSucceeded : True <-- required before devtunnel will workRate Limits & Performance Expectations
CourtListener API Limits
Limit | Value | Scope |
General requests | 5,000 / hour | All endpoints |
Citation-lookup throttle |
| |
Citations per request | 250 max |
|
Text per request | 64,000 chars (~50 pages) |
|
Key distinction: the 60/min throttle counts valid citations (status 200 or 300), not requests. A single brief with 60 real cases consumes the entire minute's quota in one call. Invalid reporters and 404s do not count against the limit.
How the Server Enforces Limits
The client uses two token-bucket rate limiters:
General limiter โ 83 requests/minute burst (
floor(5000 รท 60)), keeping sustained throughput safely under the 5,000/hr capCitation limiter โ 60 citations/minute, matching the CourtListener throttle exactly
When the API returns HTTP 429, the response includes a wait_until ISO-8601 timestamp. The client parses that and waits precisely the right amount of time before retrying โ no guessing, no wasted sleep.
Performance Expectations for Large Documents
The tool docstring is read by the LLM before it writes the tool call. The courtlistener_validate_citations docstring contains explicit guidance on how to handle documents with many citations โ when to call once vs. when to split by section. This means:
Short brief (few citations): LLM calls once, results in a few seconds. No noticeable overhead.
Long document (many citations): The LLM will spend a moment thinking about the docstring guidance before writing the tool call โ planning how to split the document to avoid burning the 60/min quota in one shot. This pre-call reasoning adds a few seconds of visible "thinking" time but prevents a forced 60-second API wait mid-validation.
Dense citation document (>60 valid citations): If not split, the API will throttle after 60 valid citations and the client will pause until the wait_until window expires. Splitting by section eliminates this pause entirely.
In short: slightly longer time before the first tool call โ much shorter total wall-clock time for large documents.
CourtListener API
Getting an API Token
Create a free account
Go to your profile settings to find your API token
Tokens are 40-character hex strings
Critical: API Version
API v4 is current. v3 returns 403 Forbidden on all data endpoints.
Base URL:
https://www.courtlistener.com/api/rest/v4Auth header:
Authorization: Token {token}(NOTBearer)Must include
User-Agentheader
Key Endpoints
Endpoint | Method | Purpose |
| POST | Validate citations from text (eyecite) |
| GET | Search opinions by name, court, citation |
| GET | Get opinion cluster details |
Common Court Identifiers
ID | Court |
| Supreme Court |
| Federal Circuit |
| Circuit Courts 1-11 |
| DC Circuit |
| District of Columbia |
API Token Management
Token Resolution Priority
COURTLISTENER_API_TOKENenvironment variable โ Docker / all platformsWindows Credential Manager (via
keyringlibrary) โ Windows STDIO onlyDPAPI-encrypted file (
~/.courtlistener_api_token) โ Windows STDIO fallback (auto-migrated to Credential Manager on first access)Elicitation prompt (asks user at tool call time via FastMCP) โ STDIO only
Docker users: Only option 1 applies. Set
COURTLISTENER_API_TOKENin your.envfile. Options 2โ4 require a native Windows process and are not available inside a Linux container.
PowerShell Management
# Store token securely (Credential Manager + DPAPI backup)
.\deploy\windows_setup.ps1
# Check stored token
.\deploy\manage_api_keys.ps1 -Action check
# Test API connection
.\deploy\manage_api_keys.ps1 -Action test
# Delete stored token
.\deploy\manage_api_keys.ps1 -Action deleteEnvironment Variables
Variable | Required | Default | Description |
| Yes* | None | API token (*or use DPAPI storage) |
| No |
| Transport mode: |
| No |
| HTTP server bind address |
| No |
| HTTP server port |
| No |
| Logging level |
| No |
| Comma-separated CORS allowed origins (HTTP mode) |
| No | None | Single extra CORS origin to append (e.g. |
| No | None | Shared secret for endpoint auth. If set, all non-health requests must include |
Cross-MCP Integration
This MCP is designed to complement other legal research MCP servers:
Related MCP Servers
MCP Server | Purpose | GitHub Repository |
CourtListener Citation Validation | Citation validation & hallucination detection | |
USPTO Patent File Wrapper (PFW) | Patent prosecution history & documents | |
USPTO Patent Trial and Appeal Board (PTAB) | Post-grant challenges (IPR/PGR/CBM) | |
USPTO Final Petition Decisions (FPD) | Petition decisions during prosecution | |
USPTO Enriched Citation | AI-extracted citation intelligence from Office Actions | |
Pinecone Assistant MCP | Patent law knowledge base (MPEP, examination guidance) | |
Pinecone RAG MCP | Patent law knowledge base with custom embeddings |
Integration Patterns
CourtListener + PFW: Validate patent case citations, then pull prosecution documents for cited cases
CourtListener + PTAB: Verify PTAB decision citations in legal briefs, cross-reference with trial records
CourtListener + Pinecone: Research MPEP guidance on legal standards, then validate supporting case citations
Project Structure
courtlistener_citations_mcp/
โโโ pyproject.toml # FastMCP 3.0 beta 2, httpx, pydantic-settings
โโโ .env.example # Template for env vars
โโโ Dockerfile # Python 3.11-slim, STDIO default (HTTP via TRANSPORT=http)
โโโ docker-compose.yml # Single service, port 8000
โโโ CLAUDE.md # Claude Code guidance
โโโ README.md # This file
โโโ src/
โ โโโ courtlistener_mcp/
โ โโโ __init__.py
โ โโโ __main__.py # python -m courtlistener_mcp
โ โโโ main.py # FastMCP server + 7 tools + health check + MCP Apps
โ โโโ api/
โ โ โโโ client.py # CourtListenerClient (httpx async, rate limiting, retry)
โ โโโ config/
โ โ โโโ settings.py # Pydantic settings + Credential Manager + DPAPI fallback
โ โ โโโ api_constants.py # No magic numbers
โ โ โโโ tool_guidance.py # Sectioned guidance (7 sections, 80-95% token reduction)
โ โ โโโ log_config.py # File-based logging with rotation
โ โโโ shared/
โ โ โโโ dpapi_crypto.py # DPAPI encryption (Windows only)
โ โ โโโ secure_storage.py # Unified API token storage
โ โ โโโ log_sanitizer.py # Automatic sensitive data sanitization
โ โ โโโ safe_logger.py # SafeLogger with auto-sanitization
โ โโโ prompts/
โ โ โโโ __init__.py
โ โ โโโ validate_legal_brief.py # Full citation audit prompt (Step 0 + 3-tool chain)
โ โโโ ui/
โ โโโ citation_view.py # MCP Apps interactive citation results UI
โโโ skill/
โ โโโ courtlistener-citation-validator/
โ โโโ SKILL.md # Claude Code skill: validate citations in legal documents
โโโ deploy/
โ โโโ windows_setup.ps1 # Full Windows deployment (uv, venv, token, Claude Desktop)
โ โโโ manage_api_keys.ps1 # Token management (check/test/delete)
โ โโโ start_devtunnel.ps1 # Dev tunnel launcher for CoPilot Studio / Claude.ai
โโโ tests/
โโโ conftest.py # Shared fixtures (api_client, sample responses, global reset)
โโโ unit/
โ โโโ test_client.py # RateLimiter, chunking, throttle parsing, HTTP errors,
โ โ # citation validation, security logging
โ โโโ test_extract_citations.py # eyecite extraction: all citation types, id/supra resolution,
โ โ # empty text guard, async JSON return
โ โโโ test_log_sanitizer.py # Token masking, ANSI/injection filtering, truncation
โ โโโ test_secure_storage.py # Keyring exception handling, token storage/migration
โโโ integration/
โโโ test_mcp_tools.py # _handle_client_errors, client reset on auth failure,
# concurrent init single-instance guarantee
Runtime Generated Files (not in repo):
~/.courtlistener_citations_mcp/
โโโ logs/
โ โโโ courtlistener_citations_mcp.log # Application logs (10MB rotation, 5 backups)
โ โโโ security.log # Security events (10MB rotation, 10 backups)
โโโ .courtlistener_api_token # Encrypted API token (DPAPI, Windows only)Troubleshooting
Common Issues
API Token Issues
Symptom:
ToolError: CourtListener API token not configuredSolution: Set
COURTLISTENER_API_TOKENenv var, run.\deploy\windows_setup.ps1, or let elicitation prompt you
Docker: Token Not Found / Blank Token Warning
Symptom:
The "COURTLISTENER_API_TOKEN" variable is not set. Defaulting to a blank string.indocker compose upoutputCause: Docker containers run Linux โ Windows Credential Manager and DPAPI are not available inside the container
Solution: Create a
.envfile in the project root containingCOURTLISTENER_API_TOKEN=your_token, thendocker compose down && docker compose up -d
Docker: Port Already Allocated
Symptom:
Bind for 0.0.0.0:8000 failed: port is already allocatedCause: Another container (e.g., graphiti-mcp) is using port 8000
Solution: Stop the conflicting container first (
docker stop <name>), thendocker compose up -dโ do not usedocker starton a previously-failed container as it won't get the port binding
API v3 vs v4
Symptom: 403 Forbidden on all data endpoints
Cause: Using API v3 URL instead of v4
Solution: Ensure base URL is
https://www.courtlistener.com/api/rest/v4
Auth Header Format
Symptom: 401 Unauthorized
Cause: Using
Bearerinstead ofTokenSolution: Auth header must be
Authorization: Token {key}(NOTBearer {key})
Citation-Lookup Returns Empty
Symptom: Citation exists but returns no results
Cause: Supreme Court cases may be indexed under different reporters (e.g., "573 U.S. 208" may not match but "134 S. Ct. 2347" does)
Solution: This is why the fallback chain exists - use
courtlistener_search_caseswith the case name
MCP Server Won't Start
Cause: Missing dependencies or incorrect paths
Solution: Re-run setup script, restart all PowerShell windows, restart Claude Desktop and verify configuration
Virtual Environment Issues (Windows Setup)
Symptom: "No pyvenv.cfg file" errors during
windows_setup.ps1Cause: Claude Desktop locks
.venvfiles when runningSolution:
Close Claude Desktop completely before running setup script
Remove
.venvfolder:Remove-Item ./.venv -Force -Recurse -ErrorAction SilentlyContinueRun
.\deploy\windows_setup.ps1again
Resetting MCP Installation
# Navigate to the project directory
cd C:\Users\YOUR_USERNAME\courtlistener_citations_mcp
# Remove Python cache directories
Get-ChildItem -Path ./src -Directory -Recurse -Force | Where-Object { $_.Name -eq '__pycache__' } | Remove-Item -Recurse -Force
# Remove virtual environment
if (Test-Path ".venv") {
Remove-Item ./.venv -Force -Recurse -ErrorAction SilentlyContinue
}
# Now you can run the setup script again
.\deploy\windows_setup.ps1Security & Production Readiness
Security Features
Windows Credential Manager + DPAPI - API tokens stored in Windows Credential Manager (via
keyring) as the primary secure store, with a DPAPI-encrypted file fallback (user-specific encryption + 256-bit entropy). Tokens are automatically migrated from file to Credential Manager on first access.SafeLogger with Auto-Sanitization - Automatically masks 40-char hex tokens,
Token <hex>auth headers, passwords, IPs, and emails in all log messages (CWE-532)File-Based Logging with Rotation - Persistent audit trail with 10MB rotation, separate security logs with 10 backups (CWE-778)
Environment variable tokens - No hardcoded credentials anywhere in codebase
Tokens never logged - API tokens never included in error messages or log output
User-Agentheader - Identifies the MCP to CourtListenerRate limiting - Dual token-bucket limiters (83 req/min general, 60 valid-citations/min for citation-lookup) prevent API abuse and stay within CourtListener's 5,000/hr cap
Endpoint auth (opt-in) - Set
INTERNAL_AUTH_SECRETto require anx-api-keyheader on all non-health requests. Leave unset for open access (local dev, trusted internal networks). In gateway deployments, the gateway injectsx-api-keyat the proxy layer so clients do not need to configure the header manually.
Error Handling
Retry with exponential backoff - 3 attempts for transient failures (429, 5xx)
Smart retry strategy - Doesn't retry authentication errors or client errors (4xx)
Graceful fallback - DPAPI unavailable on Linux? Falls back to env var (no crash)
Connection pooling - httpx async client with keep-alive for performance
Contributing
Fork the repository
Create a feature branch
Add tests for new functionality
Ensure all tests pass
Submit a pull request
License
MIT License
Disclaimer
THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND.
Independent Project Notice: This is an independent personal project and is not affiliated with, endorsed by, or sponsored by Free Law Project or CourtListener.
The author makes no representations or warranties, express or implied, including but not limited to:
Accuracy & AI-Generated Content: No guarantee of data accuracy, completeness, or fitness for any purpose. Users are specifically cautioned that outputs generated or assisted by Artificial Intelligence (AI) components may be inaccurate, incomplete, fictionalized, or represent "hallucinations" by the AI model. This tool helps detect such hallucinations but cannot guarantee 100% detection.
Availability: CourtListener API dependencies may cause service interruptions.
Legal Advice: This tool provides data access and processing only, not legal counsel. All results must be independently verified, critically analyzed, and professionally judged by qualified legal professionals.
Coverage Gaps: CourtListener does not index every case. A citation returning 404 does NOT definitively mean it is fabricated - it may simply not be in the database. Always use the fallback chain and exercise professional judgment.
Commercial Use: Users must verify CourtListener terms of service for commercial applications.
LIMITATION OF LIABILITY: Under no circumstances shall the author be liable for any direct, indirect, incidental, special, or consequential damages arising from use of this software, even if advised of the possibility of such damages.
USER RESPONSIBILITY
Independent Verification: All outputs MUST be thoroughly reviewed, independently verified, and corrected by a human prior to any reliance, action, or submission to any court or entity.
Professional Judgment: This tool is a supplement, not a substitute, for your own professional judgment and expertise.
Security: Maintain secure handling of API credentials.
Testing: Test thoroughly before production use.
By using this software, you acknowledge that you have read this disclaimer and agree to use the software at your own risk, accepting full responsibility for all outcomes.
Note for Legal Professionals: While this tool validates citations against the CourtListener database, a "valid" result only confirms the citation exists in CourtListener's index - it does not verify that the citation supports the legal proposition for which it is cited. Professional analysis is always required.
Related Links
CourtListener - Free legal research platform by Free Law Project
Free Law Project - Non-profit operating CourtListener
Support This Project
If you find this CourtListener Citation Validation MCP Server useful, please consider supporting the development!

Your support helps maintain and improve this open-source tool. Thank you!
Acknowledgments
Free Law Project for operating CourtListener and providing the REST API
eyecite (Free Law Project) for the local citation extraction library used in
courtlistener_extract_citationsblakeox/courtlistener-mcp โ prior CourtListener MCP implementation; some architectural patterns and tool design informed by this work
JamesANZ/us-legal-mcp โ US legal research MCP; citation validation workflow concepts referenced during design
Model Context Protocol for the MCP specification
Claude Code for development assistance, architectural guidance, and documentation
Claude Desktop for additional development support and testing
Questions? Review the troubleshooting section above, use courtlistener_citations_get_guidance(section='overview') for workflow help, or check .\deploy\manage_api_keys.ps1 -Action test to verify your API connection.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/john-walkoe/courtlistener_citations_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server