docketrouter
DocumentationBrowse
API reference

MCP server

Everything on Retrieval and Citations, callable as tools by an AI agent instead of as REST endpoints. Same corpora, same auth, same rate limits and metering: a tool call counts as a call to the REST endpoint it wraps, so the two never disagree about your usage.

GET/api/mcppublicA small JSON description of the server, for a human or a crawler.
POST/api/mcpkey or sessionThe MCP endpoint: JSON-RPC 2.0, Streamable HTTP transport.

Why a separate endpoint

DocketRouter does not sell corpus downloads. The corpora are hosted as endpoints; MCP is the interface for an agent that would otherwise have to be told to call four separate REST routes by hand.

If you are writing your own HTTP client rather than pointing an MCP-aware app at this endpoint, skip to the wire format.

Connect a client

Point any MCP-aware client at the endpoint with your key as a bearer token. No local process, no stdio transport to manage.

Claude Code

terminal
claude mcp add docketrouter --transport http https://docketrouter.ai/api/mcp --header "Authorization: Bearer dr-…"

Claude Desktop

claude_desktop_config.json (mcpServers)
{
  "mcpServers": {
    "docketrouter": {
      "url": "https://docketrouter.ai/api/mcp",
      "transport": "http",
      "headers": { "Authorization": "Bearer dr-…" }
    }
  }
}

Cursor

.cursor/mcp.json
{
  "mcpServers": {
    "docketrouter": {
      "url": "https://docketrouter.ai/api/mcp",
      "headers": { "Authorization": "Bearer dr-…" }
    }
  }
}

A generic HTTP MCP client

POST JSON-RPC 2.0 to https://docketrouter.ai/api/mcp with Authorization: Bearer dr-… and content-type: application/json. Send initialize, then notifications/initialized, then tools/list or tools/call as needed. Server-sent events are not required: every response here is a single value, returned as one application/json body.

Tools

ToolWrapsArguments
search_texas_lawPOST /rag/queryq
search_rulesPOST /rag/rulesq
check_citationsPOST /citations/checkcitations
check_supportPOST /citations/supportcitation, proposition
get_instructionsGET /llms.txt (no key)none required

Each tool's full JSON Schema is in tools/list's response and on Featured RAGs as OpenAI and Anthropic function-calling JSON, generated from the same schema objects so all three renderings agree. get_instructions is discovery, not retrieval: it is the one tool callable with no Authorization header at all, so an agent that has not yet been given a key can still ask this server how to use it.

Instructions for your agent

The standing brief every agent gets, in the same words, from three places: the MCP initialize handshake, the get_instructions tool, and plain GET /llms.txt.

Every initialize response's instructions field carries this text, so an MCP-aware client shows it to its model automatically on connect with no extra call. An agent that loses it out of context, or that only reads tools/list and never initialize, can ask for it back at any time by calling get_instructions with no arguments (no key required), or by fetching https://docketrouter.ai/llms.txt directly. All three return byte-identical text.

Wiring a system prompt by hand instead of going through MCP -- a plain chat integration, a custom agent loop -- paste the contents of /llms.txt into the system prompt once, and repeat the same call your model would otherwise make against check_citations and check_support before it shows a user a citation, since a hand-wired prompt gets none of MCP's per-call tool enforcement for free.

GET https://docketrouter.ai/llms.txt (excerpt)
This library covers Texas case law (615,391 decisions, 1840 through 26 June 2026: the Supreme Court of Texas, the Court of Criminal Appeals, the Courts of Appeals, the Commission of Appeals of 1918 to 1945 and the Business Court), Texas statutes, Texas court and local rules, the verbatim rules corpus, and U.S. Supreme Court opinions through 29 June 2026.

For any question within that scope, call the tools and cite only what they return. Do not answer Texas or Supreme Court legal questions from memory; that is what this library is for.

For anything outside it (other states, federal courts below the Supreme Court, secondary sources, citator history, dockets and filings, administrative law, or anything decided after the index dates) these tools have nothing. Say that plainly. Do not search anyway and do not present what comes back as an answer: a lexical index always returns something, and
…

The JSON-RPC shape

For writing your own client rather than using an MCP-aware app.

initialize

request → response
--> { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-06-18" } }
<-- { "jsonrpc": "2.0", "id": 1, "result": {
      "protocolVersion": "2025-06-18",
      "capabilities": { "tools": {} },
      "serverInfo": { "name": "docketrouter", "version": "1.0.0" }
    } }

--> { "jsonrpc": "2.0", "method": "notifications/initialized" }   // no response: it is a notification

tools/list

response (abridged)
{ "jsonrpc": "2.0", "id": 2, "result": { "tools": [
  { "name": "search_texas_law", "description": "…", "inputSchema": { "type": "object", "properties": { "q": { … } }, "required": ["q"] } },
  { "name": "search_rules", "description": "…", "inputSchema": { … } },
  { "name": "check_citations", "description": "…", "inputSchema": { … } },
  { "name": "check_support", "description": "…", "inputSchema": { … } }
] } }

tools/call

request → response
--> { "jsonrpc": "2.0", "id": 3, "method": "tools/call",
      "params": { "name": "check_citations", "arguments": { "citations": ["488 U.S. 222", "999 F.9th 1"] } } }

<-- { "jsonrpc": "2.0", "id": 3, "result": {
      "content": [ { "type": "text", "text": "{\"results\":[…],\"checked\":2,\"found\":1,\"took_ms\":21}" } ],
      "structuredContent": { "results": [ /* same object, not stringified */ ], "checked": 2, "found": 1, "took_ms": 21 }
    } }

content[0].text is the JSON-encoded form of structuredContent, for a client that only reads text content blocks. Both carry the exact same body the matching REST endpoint returns.

Batching

The body may be a single JSON-RPC object or a non-empty array of them. A batch is answered with an array of responses in the same order; a request with no id (a notification) never appears in the response, including when it fails.

Errors

Protocol-level failures use JSON-RPC's own reserved codes. Everything else -- an invalid tool argument, an unresolvable auth token, a rate limit, the index being unavailable -- carries the exact message the matching REST endpoint's error.message would have, so the two are never worded differently for the same failure.

CodeMeaning
-32700Parse error: the body was not valid JSON, or was an empty array.
-32600Invalid request: not a JSON-RPC 2.0 object, or missing method.
-32601Method not found.
-32602Invalid params: an unknown tool name in tools/call, or a tool's own argument validation failed (same wording as the REST 400).
-32603Internal error: an unexpected exception, degraded rather than propagated.
-32000Server error: authentication failed, a rate limit was hit, or the underlying endpoint is unavailable (503-equivalent). Carries a data.status matching the REST status code.
A single request's HTTP status matches its REST equivalent

For a non-batch call, the overall HTTP status is the same one the wrapped REST endpoint would return (401, 429, …), with a JSON-RPC error object in the body naming the failing request's id. A batch always answers 200, since a batch response is an array covering requests that may have succeeded or failed independently.

Examples

curl https://docketrouter.ai/api/mcp \
  -H "Authorization: Bearer dr-…" -H "content-type: application/json" \
  -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": { "name": "search_texas_law", "arguments": { "q": "TRCP 21a service by email", "k": 3 } } }' \
  | jq '.result.structuredContent.hits'

Pricing and limits

Every tool call is priced the same as the REST endpoint it wraps: currently free during beta. It draws from the same per-key rate-limit bucket as that endpoint too (30 calls per minute, burst 10, for any of the four tools), so calling a tool over MCP and calling its REST route directly share one quota, not two. See Retrieval limits and Citation limits for the per-field caps (query length, citation count, and so on) each tool's arguments still enforce.

Something here wrong or missing? Mail hello@docketrouter.ai with the request_id and we will fix the docs or the API, whichever is broken.