Install the Node.js or Python client, run the MCP server with npx, call the REST API directly over HTTPS, or connect to the hosted MCP server at mcp.courtmesh.ai, which needs nothing installed. Current version 0.5.0 of all three packages, including CNR lookup, watchlists, the changes feed and webhook signature verification.
When in doubt about a parameter or a response shape, the pages in this reference are the source of truth, not a client's own README.
@courtmesh/sdk on npm. Current version 0.5.0.npm install @courtmesh/sdkimport { CourtMeshClient } from '@courtmesh/sdk';
// apiKey defaults to the COURTMESH_API_KEY environment variable
const client = new CourtMeshClient({ apiKey: process.env.COURTMESH_API_KEY });
// Keyword search
const results = await client.searchCases({
query: 'dishonour of cheque section 138',
court: 'Bombay High Court',
});
// Look a case up by CNR (1 credit, charged only when a record is returned)
const lookup = await client.getCaseByCnr('DLHC010084212021');
console.log(lookup.data.status, lookup.data.case?.nextHearingDate);Monitoring, from creating a watchlist to polling the feed and registering a webhook. See monitoring and webhooks.
// Watch CNRs: checked daily, free within your plan's cap
const watchlist = await client.createWatchlist({
name: 'Loan book, Delhi',
items: [{ cnr: 'DLHC010084212021', reference: 'LOAN-42' }],
});
// Poll the changes feed (1 credit per non-empty page, empty pages are free)
let cursor;
const page = await client.listChanges({ cursor });
for (const event of page.data) {
console.log(event.type, event.cnr, event.data);
}
cursor = page.pagination.nextCursor; // store it and poll forward
// Or receive signed webhooks
const hook = await client.createWebhook({
url: 'https://example.com/courtmesh/webhook',
});
console.log(hook.data.secret); // shown once, store it
// Each watchlist item is watching, pending, not_found, error or unavailable (taken down).
// Over a daily add limit, an add comes back cap_exceeded for that item.Verify a webhook delivery:
import express from 'express';
import { verifyWebhookSignature, WebhookSignatureError } from '@courtmesh/sdk';
const app = express();
// Verify against the RAW body, not a parsed object
app.post('/courtmesh/webhook', express.raw({ type: 'application/json' }), (req, res) => {
try {
const event = verifyWebhookSignature(
req.body,
req.get('CourtMesh-Signature'),
process.env.COURTMESH_WEBHOOK_SECRET,
);
// Dedupe on event.id: delivery is at least once
res.sendStatus(200);
} catch (err) {
if (err instanceof WebhookSignatureError) return res.sendStatus(400);
throw err;
}
});courtmesh on PyPI. Current version 0.5.0.pip install courtmeshfrom courtmesh import CourtMesh
# api_key defaults to the COURTMESH_API_KEY environment variable
client = CourtMesh(api_key="cm-YOUR_KEY_HERE")
# Keyword search
results = client.search_cases(
query="dishonour of cheque section 138",
court="Bombay High Court",
)
# Look a case up by CNR (1 credit, charged only when a record is returned)
lookup = client.get_case_by_cnr("DLHC010084212021")
print(lookup.data["status"], lookup.data["case"]["nextHearingDate"])Monitoring:
# Watch CNRs: checked daily, free within your plan's cap
watchlist = client.create_watchlist(
name="Loan book, Delhi",
items=[{"cnr": "DLHC010084212021", "reference": "LOAN-42"}],
)
# Poll the changes feed (1 credit per non-empty page, empty pages are free)
page = client.list_changes(cursor=None)
for event in page.data:
print(event["type"], event["cnr"], event["data"])
cursor = page.next_cursor # store it and poll forward
# Or receive signed webhooks
hook = client.create_webhook(url="https://example.com/courtmesh/webhook")
print(hook.data["secret"]) # shown once, store it
# Each watchlist item is watching, pending, not_found, error or unavailable (taken down).
# Over a daily add limit, an add comes back cap_exceeded for that item.Verify a webhook delivery:
import os
from flask import Flask, request
from courtmesh import verify_webhook_signature, WebhookSignatureError
app = Flask(__name__)
@app.post("/courtmesh/webhook")
def courtmesh_webhook():
try:
# Verify against the RAW body, not request.json
event = verify_webhook_signature(
request.get_data(),
request.headers.get("CourtMesh-Signature"),
os.environ["COURTMESH_WEBHOOK_SECRET"],
)
except WebhookSignatureError:
return "", 400
# Dedupe on event["id"]: delivery is at least once
return "", 200mcp.courtmesh.ai is live and exposes this same corpus to Claude, Cursor and other Model Context Protocol clients, with nothing to install. See the MCP server product page for what it can do.Point any MCP client that supports a remote streamable HTTP server at the URL below and pass your CourtMesh API key as a bearer token:
{
"mcpServers": {
"courtmesh": {
"url": "https://mcp.courtmesh.ai/mcp",
"headers": {
"Authorization": "Bearer cm-YOUR_KEY_HERE"
}
}
}
}Or add it from the Claude Code CLI:
claude mcp add --transport http courtmesh https://mcp.courtmesh.ai/mcp \
--header "Authorization: Bearer cm-YOUR_KEY_HERE"# For a client that can only configure a URL, pass the key as a token query parameter
https://mcp.courtmesh.ai/mcp?token=cm-YOUR_KEY_HEREPrefer to run it yourself? The same server is on npm as @courtmesh/mcp-server 0.5.0, launched with npx and your API key in the environment:
{
"mcpServers": {
"courtmesh": {
"command": "npx",
"args": ["-y", "@courtmesh/mcp-server"],
"env": { "COURTMESH_API_KEY": "cm-YOUR_KEY_HERE" }
}
}
}claude mcp add courtmesh --env COURTMESH_API_KEY=cm-YOUR_KEY_HERE -- npx -y @courtmesh/mcp-servercourtmesh-postman, a ready made collection covering every endpoint on this reference.# Import directly from GitHub, or download and import manually
# in Postman: File > Import > Link
https://raw.githubusercontent.com/thinkscoop-technologies/courtmesh-postman/main/CourtMesh.postman_collection.json