Courtlistener MCP
An MCP server that bridges Anthropic’s Claude (and other LLMs) with the CourtListener API for live legal data—opinions, dockets, court records, and more. Designed to power legal research and compliance tools with transparency, reliability, and fewer hallucinations. Scalable, open, and easy to extend
Installation
npx courtlistener-mcpAsk AI about Courtlistener MCP
Powered by Claude · Grounded in docs
I know everything about Courtlistener MCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
CourtListener MCP Server
Production-ready Model Context Protocol (MCP) server for CourtListener legal
data. It exposes legal research tools over MCP (stdio and HTTP), with
deployment-ready support for local use, self-hosted remote deployments, hosted
Cloudflare Workers OAuth, structured logging, caching, and CI testing.
What This Repository Provides
- MCP server built on
@modelcontextprotocol/sdk - 49 legal research tools backed by CourtListener API v4
- Three deployment contracts: local
stdio, self-hosted remote HTTP, and hosted remote OAuth - Hosted MCP OAuth transport via Cloudflare Workers OAuth Provider
- Worker-owned browser auth handoff for hosted sign-in and approval
- Built-in health checks and metrics endpoints for operations
- Prebuilt MCP client config examples in
configs/
Repository Structure
src/core server, tool handlers, API integration, worker runtimeconfigs/ready-to-use MCP client configs for local, self-hosted, and hosted clientsdocs/deployment, testing, and operational documentationtest/unit/integration/e2e test suitesscripts/deployment helpers, diagnostics, inspector tooling, key management
Quick Start
1. Use the hosted remote endpoint (fastest)
Best for ChatGPT, Claude, Codex, and other remote clients that should not run the server locally:
{
"mcpServers": {
"courtlistener": {
"url": "https://courtlistener-mcp.<subdomain>.workers.dev/mcp",
"transport": "streamable-http"
}
}
}
2. Run locally from a checkout
Best for privacy, local development, and bring-your-own-auth setups. The npm
package is not currently published, so the local stdio server should be run
from this repository checkout:
- Download ZIP: https://github.com/blakeox/courtlistener-mcp/archive/refs/heads/main.zip
- Download tar.gz: https://github.com/blakeox/courtlistener-mcp/archive/refs/heads/main.tar.gz
git clone https://github.com/blakeox/courtlistener-mcp.git
cd courtlistener-mcp
pnpm install
pnpm build
node dist/index.js --setup
Or run it directly:
node dist/index.js
If you want a local shell command after building:
npm link
courtlistener-mcp --setup
3. Self-host the HTTP runtime from source
git clone https://github.com/blakeox/courtlistener-mcp.git
cd courtlistener-mcp
pnpm install
pnpm build
node dist/http.js
4. Self-host with Docker
cp .env.production .env
docker compose -f docker-compose.prod.yml up -d
Publishing to npm
This repository is configured to publish from .github/workflows/release.yml
when you push a version tag such as v1.0.5.
You have two supported auth paths:
- Repository secret: create an npm publish token and store it as the GitHub
Actions secret
NPM_TOKEN. - Trusted publishing: connect the npm package to this GitHub repository and let npm trust GitHub Actions OIDC, with no token stored in GitHub.
Once one of those is configured, publish with:
git tag v1.0.5
git push origin v1.0.5
Deployment Modes
1. Local mode (stdio)
- Run the MCP server on the same machine as the client
- No hosted auth required
- Best for privacy-sensitive workflows, local development, and bring-your-own-hosting
2. Self-hosted remote mode
- Deploy the HTTP/streamable HTTP runtime on your own infrastructure
- Bring your own auth if you need it (
OIDC_*, service token, proxy auth, etc.) - Best for teams that want remote access without using the hosted CourtListener endpoint
3. Hosted remote mode
- Use the CourtListener Cloudflare Worker as the remote MCP endpoint
- The Worker is the MCP OAuth server and exposes
/mcp,/oauth/authorize,/token,/register, and discovery metadata - The Worker also owns the browser auth handoff routes on the same origin
(
/auth/start,/auth/callback,/oauth/approve,/oauth/logout) - Legacy
/authorize,/auth/approve, and/auth/logoutaliases remain in the runtime for compatibility, but production now publishes the/oauth/*endpoints as canonical - Keep Logto as the current upstream hosted identity provider if you want a managed OIDC tenant; the Worker-facing contract stays generic OIDC
- Best for ChatGPT, Claude, Codex, and browser-native remote clients
MCP Client Configuration
Prebuilt configs are provided in configs/:
local-stdio.jsonself-hosted-remote-http.jsonhosted-remote-claude.jsonhosted-oauth-chatgpt.jsonhosted-oauth-codex.jsonclaude-desktop.jsonclaude-desktop-remote.jsoncursor.jsoncontinue-dev.jsonvscode-copilot.jsonzed.jsonopenai-chatgpt.jsoncodex.json
Explicit contract examples:
configs/local-stdio.jsonfor localstdioconfigs/self-hosted-remote-http.jsonfor self-hosted remote HTTPconfigs/hosted-remote-claude.jsonfor hosted remote use with Claude-style clientsconfigs/hosted-oauth-chatgpt.jsonfor hosted remote OAuth with ChatGPT-style clientsconfigs/hosted-oauth-codex.jsonfor hosted remote OAuth with Codex-style clients
Legacy filenames are still shipped for compatibility:
configs/codex.jsonfor direct HTTP transportconfigs/openai-chatgpt.jsonfor hosted OAuthconfigs/claude-desktop-remote.jsonfor hosted remote usemcp-config.jsonfor local/bridge variants used in development
Tool Catalog (33)
Search and discovery
search_opinionssearch_casesadvanced_searchsmart_search
Cases and opinions
get_case_detailsget_related_casesget_opinion_textlookup_citationanalyze_case_authoritiesanalyze_legal_argumentget_citation_networkget_comprehensive_case_analysis
Courts and judges
list_courtsget_judgesget_judgeget_comprehensive_judge_profile
Dockets and RECAP
get_docketsget_docketget_docket_entriesget_recap_documentsget_recap_documentget_enhanced_recap_data
Financial and parties
get_financial_disclosuresget_financial_disclosureget_financial_disclosure_detailsget_parties_and_attorneys
Analytics and monitoring
get_visualization_dataget_bulk_dataget_bankruptcy_datamanage_alertsvalidate_citations
Oral arguments
get_oral_argumentsget_oral_argument
For authoritative tool schema/arguments, use MCP tools/list from your client.
Local Development
Prerequisites
- Node.js 18+
pnpm- CourtListener API token (recommended for higher limits)
Install and build
pnpm install
pnpm build
Run
pnpm run mcp
Diagnostics
pnpm run doctor
pnpm run cloudflare:check
pnpm run ci:auth-release-gate
Deployment (Cloudflare Workers)
pnpm install
wrangler secret put COURTLISTENER_API_KEY
wrangler secret put MCP_UI_SESSION_SECRET
wrangler secret put OIDC_ISSUER
wrangler secret put OIDC_AUDIENCE
wrangler secret put MCP_OAUTH_REGISTRATION_TOKEN_SECRET
# Optional shared token auth
wrangler secret put MCP_AUTH_TOKEN
# Optional: set MCP_OAUTH_REGISTRATION_TOKEN_TTL_SECONDS in wrangler vars (defaults to 86400)
# Optional: set MCP_TRUST_CLOUDFLARE_ACCESS_ACKNOWLEDGED=true only if intentionally trusting Cloudflare Access assertions/identity headers
pnpm run cloudflare:check
pnpm run cloudflare:deploy
Endpoints after deploy:
GET /healthPOST /mcp(primary MCP endpoint)GET /sse(legacy SSE compatibility path)GET/POST /authorizePOST /tokenPOST /registerGET /.well-known/oauth-authorization-serverGET /.well-known/oauth-protected-resource
Web UX Wave (SPA)
- ✅ UX15–UX19 complete: accessibility AA hardening, design-system consolidation, performance UX optimizations, and dark-mode visual parity are now shipped.
- âś… Validation safety pass:
pnpm run test:spa,pnpm run build, andpnpm run typecheckare the required UX-wave release gate. - Control Center (
/app/control-center): live session/auth/key/runtime posture with a guided MCP checklist. - Protocol explorer: initialize/tool/resource/prompt discovery surfaced directly in Control Center metadata panels.
- Async operator workspace (
/app/playground): queue async tool calls (__mcp_async), monitor lifecycle state, deep-link job details, cancel/retry, and fetch results. - Recovery UX: cross-page recovery status banners plus safe fallback routes back to login, keys, and Control Center.
Auth Model by Deployment Mode
Hosted remote mode: Worker OAuth
Cloudflare OAuth is the primary hosted auth path for remote MCP routes.
-
The Worker is the OAuth authorization/resource server for MCP clients
-
The Worker serves the minimal auth handoff routes on the same origin
-
Remote MCP clients connect directly to the Worker
-
OAuth endpoints:
GET/POST /authorizePOST /tokenPOST /register
-
Discovery endpoints:
GET /.well-known/oauth-authorization-serverGET /.well-known/oauth-protected-resource
-
/authorizeresolves identity from:- Signed UI session (
clmcp_ui) when present - Cloudflare Access identity headers (
cf-access-authenticated-user-idorcf-access-authenticated-user-email) only whenMCP_TRUST_CLOUDFLARE_ACCESS_IDENTITY_HEADERS=true MCP_OAUTH_DEV_USER_IDonly whenMCP_ALLOW_DEV_FALLBACK=true(development fallback only; unsafe outside controlled dev and blocked by startup invariants whenNODE_ENV=production)
- Signed UI session (
-
If unresolved,
/authorizeredirects to same-origin/auth/start?return_to=<authorize_url>when Worker-native hosted auth config is present -
POST /api/session/bootstrapremains the Worker-native bearer-to-session bootstrap endpoint for trusted same-origin/session handoff cases -
Same-origin Worker auth handoff:
GET /auth/startGET /auth/callbackGET/POST /auth/approveGET/POST /auth/logout(GETrenders a confirmation form;POSTperforms the logout)- Worker-native hosted auth expects
OIDC_ISSUER,MCP_UI_SESSION_SECRET, and a complete upstream OIDC client pair - Required upstream pair:
MCP_AUTH_OIDC_CLIENT_ID+MCP_AUTH_OIDC_CLIENT_SECRET - As an alternative browser-auth boundary, protect
/authorizeand/auth/approvewith Cloudflare Access and enableMCP_TRUST_CLOUDFLARE_ACCESS_IDENTITY_HEADERS=trueplusMCP_TRUST_CLOUDFLARE_ACCESS_ACKNOWLEDGED=true; the Worker will bootstrap its own same-origin UI session from trusted Access identity headers before rendering the approval step - Partial
MCP_AUTH_OIDC_CLIENT_*config fails closed - Dynamic client-registration management tokens should use a dedicated
MCP_OAUTH_REGISTRATION_TOKEN_SECRET; otherwise they fall back toMCP_UI_SESSION_SECRETorCOURTLISTENER_API_KEY MCP_OAUTH_REGISTRATION_TOKEN_TTL_SECONDSdefaults to 86400 and should be set explicitly for hosted deployments- Browser-session authorization now stops at an explicit same-site approval
screen before the Worker completes
/authorize - Hosted-auth probe responses emit
X-Hosted-Auth-*readiness headers with a concrete reason, coarse failure category, stable low-cardinality signal/failure flags, stable flow correlation ID, flow outcome, credential source, and config-error count - Route-level rate limit controls:
MCP_SESSION_BOOTSTRAP_RATE_LIMIT_MAXMCP_SESSION_BOOTSTRAP_RATE_LIMIT_WINDOW_SECONDSMCP_SESSION_BOOTSTRAP_RATE_LIMIT_BLOCK_SECONDS
-
Usage dashboard endpoint:
GET /api/usagereturns per-user counters (totalRequests,dailyRequests,byRoute,lastSeenAt)
Self-hosted remote mode: bring your own auth
- Optional OIDC bearer validation:
OIDC_ISSUEROIDC_AUDIENCEOIDC_JWKS_URLOIDC_REQUIRED_SCOPE
- Optional trusted Cloudflare Access header acceptance:
MCP_TRUST_CLOUDFLARE_ACCESS_JWT_ASSERTION=trueonly when the Worker is deployed behind Cloudflare Access or another edge that strips/spoof-proofsCF-Access-Jwt-AssertionMCP_TRUST_CLOUDFLARE_ACCESS_IDENTITY_HEADERS=trueonly when/authorizeis deployed behind Cloudflare Access or another edge that strips/spoof-proofscf-access-authenticated-user-*MCP_TRUST_CLOUDFLARE_ACCESS_ACKNOWLEDGED=trueis required by deploy checks before either scoped trust flag is allowed- Without those explicit per-surface flags, the Worker ignores
CF-Access-Jwt-Assertionandcf-access-authenticated-user-* MCP_TRUST_CLOUDFLARE_ACCESS_HEADERSis deprecated and ignored
- Optional service-token path:
MCP_AUTH_TOKENMCP_SERVICE_TOKEN_HEADER
Use this mode when you want the CourtListener MCP runtime but need to keep identity, secrets, and deployment policy inside your own infrastructure.
Local mode: no hosted auth required
- Local
stdioclients do not need the hosted OAuth surface - Users typically provide their own
COURTLISTENER_API_KEY - This is the simplest path for desktop-local MCP clients and development
Removed Legacy UI/Auth Endpoints
The following legacy UI endpoints are disabled in the hard cutover and return
410:
/api/login*/api/logout*/api/signup*/api/password*/api/keys*/oauth/consent
Canonical hosted OAuth contract values (paths, grants, response types, scopes,
PKCE methods, priority clients) live in src/auth/oauth-contract.ts.
Hosted auth rollout checks
Before promoting a hosted Worker deploy, verify:
pnpm run cloudflare:checkis clean except for intentional deprecation warningshttps://<worker>/auth/start?continue=1returns302- a real
/authorizebrowser journey reaches/auth/approvebefore OAuth completion - DCR management token rotation is independent of UI session rotation by setting
MCP_OAUTH_REGISTRATION_TOKEN_SECRET - any Cloudflare Access trust flags are paired with
MCP_TRUST_CLOUDFLARE_ACCESS_ACKNOWLEDGED=true
Runtime and Observability
When metrics are enabled, local server endpoints include:
GET http://localhost:3001/healthGET http://localhost:3001/metricsGET http://localhost:3001/cache
Useful runtime variables:
CACHE_ENABLEDCACHE_TTLLOG_LEVELLOG_FORMATMETRICS_ENABLEDMETRICS_PORTNODE_ENV
Testing
Core tests
pnpm run test:unit
pnpm run test:integration
# install Chromium once before running the default browser-inclusive suite
pnpm exec playwright install chromium
# default repository gate: unit + integration + targeted SPA auth Vitest + auth Playwright
pnpm test
pnpm run coverage
pnpm run coverage:check
MCP protocol and inspector
pnpm run test:mcp
pnpm run ci:test-inspector:enhanced
pnpm run ci:test-inspector:enhanced:extended
pnpm run ci:test-inspector:performance
Release hardening performance gates
pnpm run ci:load-profile-suite -- --light --base-url http://127.0.0.1:3002
pnpm run ci:perf-gate -- baseline.json current.json
pnpm run ci:hardening:soak-leak-checks -- --light --base-url http://127.0.0.1:3002
pnpm run ci:release-readiness-gate -- --light --base-url http://127.0.0.1:3002
CI runs these gates in warn mode for pull requests/non-protected branches, and
strict fail mode for main/master/release/* and v* tags.
Optional local GitHub Actions simulation
act -W .github/workflows/ci.yml
Security and Contribution
- Security policy:
SECURITY.md - Contribution guide:
CONTRIBUTING.md - Architecture details:
ARCHITECTURE.md
License
MIT. See LICENSE.
