lex-scholar-api
lex-scholar-api
Dependency-free Python client + single-endpoint MCP server federating nine open-access legal scholarship indexes, for the SOCAR L&C agents (Copilot Studio Digital Twin and the Claude Assistant).
Status (2026-07-25): working, 20/20 live tests passing. One
/mcpendpoint, ten upstream indexes, no authentication anywhere, pure Python standard library on a stock Python 3.9+. Built to the same template as the siblingeqanun-apiandresourcecontracts-api.
Why this exists
Peer-reviewed legal scholarship is scattered across national indexes that do not talk to each other: Brazilian doctrine is in SciELO, French in HAL, Spanish in Dialnet, Indonesian and Iranian in DOAJ, US law reviews in Law Review Commons. Asking one comparative-law question meant nine different searches.
This server makes it one call — and, critically, does not fan out blindly. A deterministic router reads the question and picks the 2-3 indexes that can actually answer it.
Two design commitments
One endpoint, many sources. source is a tool parameter, not a deployment.
Adding a tenth index later changes nothing for the agent or the connector.
Multi-jurisdiction by construction. compare_jurisdictions runs one question
across several countries and returns the answers grouped, each routed to its
own native index — the contrast is the deliverable, not a merged ranking.
Sources (all verified live, no auth)
Source | Law filter | Peer review | Full text | Volume (law) |
DOAJ — the spine |
| guaranteed ( | abstract + link | 268,222 articles / 1,265 journals |
Law Review Commons | 67 OAI subject sets | ✗ student-edited | PDF link | 351,887 (oil-gas 845, energy 1,305, arbitration 2,082) |
SciELO |
| curated | real body text | 26,003 articles, 36 collections |
HAL (FR) |
|
| PDF + TEI | 236,486 / 26,422 OA |
Dialnet (ES) |
| mixed | ✗ discovery only | 95,402 |
DergiPark (TR) | 19 verified law-journal setSpecs | unknown (mostly hakemli) | abstract + link | 19 Turkish law journals |
OpenAIRE |
|
| link | 582,820 |
Crossref | — | — | — | DOI resolver |
Unpaywall | — | — | locator | DOI → open copy |
OpenAlex ⚠ metered |
| inferred | link | 2,244,618 / 362,231 OA |
peer_reviewed is tri-state on every record: true (source guarantees it),
false (known not to be — preprints, US student-edited law reviews), null
(unknown). Never assume; peer_reviewed_only=true keeps only true.
Install / requirements
None. Pure standard library, Python 3.9+. Optionally set OPENALEX_API_KEY to
raise OpenAlex's metered budget ~100x — everything works without it, and the
router simply holds OpenAlex back when its anonymous budget runs low.
Library
from lexscholar import LexScholarClient
c = LexScholarClient()
# Federated search — the router picks the sources
res = c.search("force majeure", peer_reviewed_only=True, limit=10)
print(res["sources_queried"], res["routing_reasons"])
# One question, several jurisdictions, grouped answers
cmp = c.compare_jurisdictions("stabilization clause", ["FR", "BR", "ID", "TR"])
# Real body text (SciELO), paginated
ft = c.get_fulltext("scielo", "S1806-64452007000100004", collection="scl")
c.resolve_doi("10.1093/jiel/jgaa002")
c.list_sources()CLI
python3 -m lexscholar search "force majeure" --peer-reviewed --brief -n 10
python3 -m lexscholar search "arbitraje de inversiones" --jurisdiction ES
python3 -m lexscholar compare "stabilization clause" FR BR ID TR
python3 -m lexscholar fulltext scielo S1806-64452007000100004 --out article.txt
python3 -m lexscholar doi 10.1093/jiel/jgaa002
python3 -m lexscholar sourcesMCP server
python3 server.py # stdio
python3 server.py --transport http --host 0.0.0.0 --port 8000 # http://<host>:8000/mcpEnv fallbacks: LEXSCHOLAR_MCP_TRANSPORT, LEXSCHOLAR_MCP_HOST, LEXSCHOLAR_MCP_PORT.
Tools
Tool | Purpose |
| routed federated search; reports |
| one question across N countries, grouped per jurisdiction |
| full normalized metadata by source + id |
| body text, paginated; says so when only a PDF link exists |
| Crossref metadata + Unpaywall open copy |
| capability cards incl. live OpenAlex budget |
Public HTTPS in one command
./run-public.sh # macOS / Linux.\run-public.ps1 # Windows (PowerShell has no && and cannot run .sh)Prints a https://<random>.trycloudflare.com/mcp URL. Quick-tunnel hostnames
rotate every run; use a named Cloudflare tunnel for a stable URL.
How routing works
Signal | Route |
DOI in the query | Crossref + Unpaywall only — discovery skipped |
| that country's native index (BR→SciELO, FR→HAL, ES→Dialnet, AZ→OpenAlex) |
query language | es/pt→SciELO+Dialnet, fr→HAL, de→OpenAIRE, tr→DergiPark+DOAJ, ru→DOAJ+OpenAlex |
energy/arbitration vocabulary | + Law Review Commons (suppressed if the query is scoped to a non-US country) |
| drops preprint and student-edited sources |
OpenAlex budget low | OpenAlex skipped before it 429s, with the reason reported |
always | DOAJ anchors — except where it demonstrably has nothing (AZ, IN, JP, AE) |
Override with source="doaj,hal" or source="all".
Smoke test
python3 examples/smoke_test.py20 assertions across routing, federation, peer-review filtering, record shape, multi-jurisdiction comparison, full text, DOI resolution and capability cards.
Verification highlights (2026-07-25)
search_legal_scholarship("stabilization clause", peer_reviewed_only=true)→ top hit "The Stabilization Clause of the Baku-Tbilisi-Ceyhan Pipeline", 0.4s, DOAJ only.compare_jurisdictions("arbitration", [FR,BR,ID,AZ])→ all four answered, each via its own index (hal,scielo,doaj,openalex).SciELO full text → 57,021 chars of clean article body.
Five upstreams in parallel = 0.96s wall clock.
Governance
Read-only research over public open-access content. Two obligations travel with
the data and are surfaced on every record via license and citation:
DOAJ
robots.txtsignalsai-train=no. The API/OAI are separate documented machine interfaces and the metadata is CC0, so retrieve-and-cite is consistent with that signal — model training is not.Dialnet
dc:rightsrequires express written consent for reproduction, so it is wired as discovery only: citations yes, redistribution no.
Law Review Commons is US student-edited (peer_reviewed=false) — authoritative
practice literature, but never to be presented as peer-reviewed scholarship.
Cite the citation field; it carries source attribution by construction.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/beerbottle90/lex-scholar-api'
If you have feedback or need assistance with the MCP directory API, please join our Discord server