MCP Hub
Back to servers

JurisCassation MCP Server

Provides AI agents with access to Moroccan Court of Cassation decisions through search tools and PDF retrieval. Enables both real-time queries against the official portal and local searches across indexed decisions.

glama
Updated
Apr 22, 2026

JurisCassation API

GraphQL + REST wrapper for juriscassation.cspj.ma — the Moroccan Court of Cassation decision portal.

Features

  • Live search — real-time passthrough to the Arabic search endpoint
  • Local search — SQLite FTS5 full-text search over scraped decisions
  • GraphQL API — type-safe queries and mutations
  • PDF proxy — cache and serve decision PDFs by encrypted ID
  • Background scraper — index all decisions into local SQLite

Quick Start

# Docker (GraphQL API on port 5091)
docker compose up -d

# Or direct
pip install -r requirements.txt
python app.py serve --port 8000

# MCP Server (port 5098, SSE transport)
# Via systemd:
sudo systemctl start juriscassation-mcp

# Or direct:
JURIS_API_BASE=http://localhost:5091 python mcp_server.py

API Endpoints

EndpointDescription
GET /graphqlGraphQL playground (interactive)
POST /graphqlGraphQL API
GET /api/pdf/{encrypted_id}Download decision PDF (proxied + cached)
GET /api/statsLocal index statistics

GraphQL Schema

Queries

# Live search against the Moroccan portal (real-time)
query {
  searchLive(chamberId: 1, sujet: "طلاق", lang: "ar", page: 1) {
    total
    page
    perPage
    items {
      encryptedId
      dossierNumber
      decisionNumber
      decisionDate
      keywordsAr
      pdfUrl
    }
  }
}

# Search the local SQLite index
query {
  searchLocal(query: "طلاق", chamberId: 1, page: 1, perPage: 20) {
    total
    page
    perPage
    items {
      id
      encryptedId
      dossierNumber
      decisionNumber
      decisionDate
      keywordsAr
      pdfUrl
    }
  }
}

# List chambers with decision counts
query {
  chambers {
    id
    nameAr
    nameFr
    nameEn
    decisionCount
  }
}

# Scraper/indexer status
query {
  scraperStatus {
    totalDecisions
    lastScrape
    chambers { id nameFr decisionCount }
  }
}

Mutations

# Scrape decisions from a chamber (Arabic endpoint with alef wildcard)
mutation {
  scrapeChamber(chamberId: 1, maxPages: 5)
}

# Scrape all pages
mutation {
  scrapeChamber(chamberId: 1, maxPages: 0)
}

Chambers

IDArabicFrenchEnglish
1الغرفة المدنيةChambre CivileCivil
2غرفة الأحوال الشخصية و الميراثStatut Personnel & SuccessionsPersonal Status & Inheritance
3الغرفة التجاريةChambre CommercialeCommercial
4الغرفة الإداريةChambre AdministrativeAdministrative
5الغرفة الاجتماعيةChambre SocialeSocial
6الغرفة الجنائيةChambre PénaleCriminal
7الغرفة العقاريةChambre ImmobilièreReal Estate

CLI Scraper

# Scrape chamber 1 (all pages)
python app.py scrape --chamber 1

# Scrape all chambers, max 50 pages each
python app.py scrape --chamber 0 --max-pages 50

# Scrape from page 100 onwards
python app.py scrape --chamber 6 --since-page 100

Architecture Notes

  • The Arabic endpoint (/Decisions/RechercheDecisionsRes) returns encrypted data-id attributes needed for PDF download
  • The French endpoint (/Decisions/RechercheDecisionsResFr) returns numeric idArretCassation IDs but no encrypted IDs
  • PDFs are downloaded via /Decisions/GetArret?encryptedId=... — no auth required
  • Empty Sujet in Arabic search returns 0 results; we use ا (alef) as a wildcard catch-all
  • SSL cert on the upstream site is broken; verify=False is required

Environment Variables

VariableDefaultDescription
JURIS_DB/data/decisions.dbSQLite database path
JURIS_PDF_CACHE/data/pdfsPDF cache directory
JURIS_CONCURRENCY3Max concurrent scrape requests
JURIS_DELAY0.5Delay between scrape pages (seconds)

MCP Server

An MCP (Model Context Protocol) server exposes all API features as AI-agent tools via SSE on port 5098.

MCP Endpoint: http://localhost:5098/sse

Tools

ToolDescription
search_decisionsLive search against juriscassation.cspj.ma
search_localFTS5 search over local SQLite index
get_decision_pdfCheck/download a decision PDF by encrypted ID
list_chambersList all 7 chambers with index counts
scrape_chamberIndex decisions from a chamber
get_statsLocal index statistics

Resources

URIDescription
juriscassation://chambersChamber reference list (AR/FR/EN)
juriscassation://statsCurrent index statistics

MCP Environment Variables

VariableDefaultDescription
JURIS_API_BASEhttp://localhost:5091GraphQL API base URL
JURIS_DB/mnt/data/juriscassation/decisions.dbSQLite path (for direct search)
MCP_PORT5098MCP server port
MCP_HOST0.0.0.0MCP server bind host
MCP_TRANSPORTsseTransport type (sse or streamable-http)

Test with mcporter

# List tools
npx mcporter list --http-url http://localhost:5098/sse --allow-http --schema

# Search
npx mcporter call search_decisions sujet=طلاق chamber_id=1 --allow-http --http-url http://localhost:5098/sse

Deployment

The app is containerized and runs on port 8000 internally, mapped to host port 5091.

Reviews

No reviews yet

Sign in to write a review