MCP

Integrate Midpage's legal database with AI assistants using the Model Context Protocol.

Note: MCP currently supports court opinion research. Statute and regulation tools are coming soon.

Base URL

https://app.midpage.ai/mcp

Authentication

Midpage supports two authentication models for MCP integrations.

Option Best for How it works
API key Server-side integrations, internal tools, and quick prototypes Your integration sends one shared API key with each request.
OAuth End-user apps, partner integrations, and multi-tenant products Each user signs in with their own Midpage account and your client sends that user's access token.

1. API Key

Use API key auth for non-interactive access, server-side jobs, or any integration that should run under one shared credential.

Generate an API key in the Developer Portal. If you need help, contact support@midpage.ai. Then send it in your MCP request headers as:

Authorization: Bearer <api_key>

2. OAuth

Use OAuth when your client should connect each user to their own Midpage account. Each user will need a Midpage account before they can sign in and authorize your client.

For most customers, the easiest setup is:

  1. Point your client at https://app.midpage.ai/mcp
  2. Let your MCP or OAuth library follow Midpage's discovery metadata and register a client automatically if it supports dynamic client registration
  3. Let the user sign in and approve access when prompted

Most MCP clients should not need pre-provisioned OAuth app credentials. Midpage's Clerk auth server supports dynamic client registration, so compatible clients can create their own credentials automatically. If your client cannot do that and needs a pre-provisioned OAuth app, contact Midpage.

Need the manual OAuth settings?

If your client supports discovery, start there. In most cases, pointing it at https://app.midpage.ai/mcp is enough. Midpage publishes protected-resource metadata on app.midpage.ai, and that metadata points clients to the Clerk authorization server. The settings below are only for cases where you need to configure the OAuth flow yourself.

Discovery

  • MCP protected-resource metadata: https://app.midpage.ai/.well-known/oauth-protected-resource/mcp
  • Clerk OAuth metadata: https://clerk.midpage.ai/.well-known/oauth-authorization-server
  • Clerk OIDC discovery: https://clerk.midpage.ai/.well-known/openid-configuration

Some older MCP clients expect OAuth authorization-server metadata on the same origin as the MCP server. Midpage currently publishes protected-resource metadata on app.midpage.ai and authorization-server metadata on the Clerk domain above, so older clients may need manual configuration using those Clerk URLs.

The current metadata advertises:

  • authorization server: https://clerk.midpage.ai
  • dynamic client registration endpoint: https://clerk.midpage.ai/oauth/register
  • PKCE challenge method: S256
  • resource scopes: profile, email

Which OAuth flow to use

  • Public clients such as desktop apps, mobile apps, browser apps, and local CLIs should use Authorization Code + PKCE (S256). Do not embed a client_secret in those clients. If you need this mode, Midpage can provision your Clerk OAuth app as a public client.
  • Confidential server-side apps can use Authorization Code and exchange the code on their backend with either client_secret_basic or client_secret_post.
  • If you need refresh tokens for long-lived sessions, request offline_access.

Minimal flow

  1. Fetch the protected-resource metadata document and read authorization_servers.
  2. Fetch the Clerk authorization-server or OIDC metadata document and use the published endpoints.
  3. Start an authorization request with response_type=code, client_id, redirect_uri, state, and the resource value from the protected-resource metadata document.
  4. Request profile email for MCP access. Add openid if your client expects an ID token. Add offline_access if you need a refresh token.
  5. Public clients must also send code_challenge and code_challenge_method=S256.
  6. Exchange the authorization code for tokens at the Clerk token endpoint, again including the same resource value.
  7. Call the MCP server with Authorization: Bearer <access_token>.

Example authorize request for a public client

GET https://clerk.midpage.ai/oauth/authorize?
  response_type=code&
  client_id=YOUR_CLIENT_ID&
  redirect_uri=https://your-app.com/oauth/callback&
  resource=https%3A%2F%2Fapp.midpage.ai&
  scope=profile%20email%20openid%20offline_access&
  state=RANDOM_VALUE&
  code_challenge=BASE64URL_SHA256(code_verifier)&
  code_challenge_method=S256

Example token exchange for a public client

curl -X POST "https://clerk.midpage.ai/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=https://your-app.com/oauth/callback" \
  -d "resource=https://app.midpage.ai" \
  -d "code_verifier=YOUR_CODE_VERIFIER"

Example token exchange for a confidential client

curl -X POST "https://clerk.midpage.ai/oauth/token" \
  -u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=https://your-app.com/oauth/callback" \
  -d "resource=https://app.midpage.ai"

Calling the MCP server

Authorization: Bearer <access_token>

Testing in Hosted MCP Clients

If you just want to try Midpage in Claude, Cursor, or another hosted MCP client, add https://app.midpage.ai/mcp and sign in with your Midpage account when prompted.

You can create a free trial account at app.midpage.ai. For production integrations, use API key auth or OAuth as described above.

Available Tools

Search US case law across federal and state courts. Returns metadata, highlights, and citator treatment data.

Parameters:

Parameter Type Required Description
queries array Yes Array of search queries (1-4) run in parallel
queries[].query string Yes Search query
queries[].negativeQuery string No Optional secondary query that ranks cases lower if they match
queries[].startDate string No Start date (inclusive, YYYY-MM-DD)
queries[].endDate string No End date (inclusive, YYYY-MM-DD)
queries[].jurisdictionType string No "federal", "state", or "state_and_federal"
queries[].circuits string[] No Federal circuits: "1"-"11", "dc", "federal_circuit", "supreme_court"
queries[].states string[] No State names (e.g., ["California", "New York"])
queries[].publishStatus string No "published", "unpublished", "unknown", "in_chambers", "separate", "errata", or "relating_to"
queries[].includeCourts string[] No Additional courts to narrow the search

If you filter on publishStatus, consider also running a parallel query with "unknown" because some jurisdictions have missing or uncertain publication metadata.

Example:

{
  "queries": [
    {
      "query": "breach of fiduciary duty elements",
      "jurisdictionType": "state_and_federal",
      "states": ["California"],
      "publishStatus": "published"
    },
    {
      "query": "breach of fiduciary duty elements",
      "jurisdictionType": "state_and_federal",
      "states": ["California"],
      "publishStatus": "unknown"
    }
  ]
}

findInOpinion

Find quotable passages within a single opinion using keyword search.

Parameters:

Parameter Type Required Description
opinionId string No* Midpage document ID (e.g., "7228818")
reporterCitation string No* Bluebook citation (e.g., "556 U.S. 662")
docket object No* Court and docket number pair
docket.courtAbbreviation string Yes Court abbreviation (e.g., "S.D.N.Y.", "9th Cir.")
docket.docketNumber string Yes Docket number (e.g., "12-cv-20100")
query string Yes Key terms to match

* Provide one of opinionId, reporterCitation, or docket

Example:

{
  "opinionId": "7228818",
  "query": "minimum contacts purposeful availment"
}

analyzeOpinion

Reads the full document, then answers your question and returns the answer alongside text excerpts.

Accepts either opinionId, reporterCitation, or docket as input.

Parameters:

Parameter Type Required Description
opinionId string No* Midpage document ID
reporterCitation string No* Bluebook citation (e.g., "556 U.S. 662")
docket object No* Court and docket number pair
docket.courtAbbreviation string Yes Court abbreviation (e.g., "S.D.N.Y.", "9th Cir.")
docket.docketNumber string Yes Docket number (e.g., "12-cv-20100")
question string Yes The legal question you want answered

* Provide one of opinionId, reporterCitation, or docket

Example:

{
  "reporterCitation": "556 U.S. 662",
  "question": "What standard does this case establish for pleading requirements?"
}