MCP Server
DocumentPro exposes document extraction, classification, and template authoring as an MCP (Model Context Protocol) server, so AI agents — Replit Agent, Lovable, Claude Code, Cursor, and any other MCP-capable client — can discover the available tools, read exact field schemas, and wire DocumentPro into the code they generate without guessing endpoint shapes or field names.
Connection
Endpoint: https://api.documentpro.ai/mcp
Transport: Streamable HTTP
Auth: x-api-key: <your DocumentPro API key>
The MCP server uses the same API key as the REST API — there is no separate credential. Your client must support sending a custom header. For example, with Claude Code:
claude mcp add --transport http documentpro https://api.documentpro.ai/mcp \
--header "x-api-key: YOUR_API_KEY"
Requests to /mcp without a valid x-api-key header are rejected at the gateway with HTTP 403 and body {"message": "Forbidden"} — note this is a 403, not a 401. Once authenticated, per-tool authorization failures surface as structured tool errors (UNAUTHORIZED, FORBIDDEN) instead — see Errors.
Other clients
Claude Desktop, or any MCP client that takes a JSON server config:
{
"mcpServers": {
"documentpro": {
"type": "http",
"url": "https://api.documentpro.ai/mcp",
"headers": { "x-api-key": "YOUR_API_KEY" }
}
}
}
Python, using the official MCP SDK:
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async with streamablehttp_client(
"https://api.documentpro.ai/mcp",
headers={"x-api-key": "YOUR_API_KEY"},
) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
Discovery
DocumentPro publishes a public MCP server card for registries and agents that discover servers programmatically:
GET https://api.documentpro.ai/.well-known/mcp/server-card.json
No authentication required. The card contains server metadata, transport details, and the full input schema for every tool below, generated from the live server so it can't drift from tools/list. Responses are cacheable for one hour.
Tools
extract_document
Submit a document for extraction. Asynchronous — returns a request_id immediately; poll check_extraction_status until the job completes.
| Input | Type | Required | Description |
|---|---|---|---|
template_id | string | yes | Template to extract with. Find one via list_templates. |
file_url | string | one of | Publicly reachable URL of the document (presigned URLs work). |
file_base64 | string | one of | Inline base64 file content, max 7 MB decoded. Prefer file_url. |
file_name | string | required with file_base64 | File name with extension, e.g. invoice.pdf. Omitting it when using file_base64 raises INVALID_INPUT. |
use_ocr | boolean | no | Force OCR for scanned/image-based documents. |
page_ranges | string | no | Limit extraction to pages, e.g. "1-3" or "1,4". |
Returns { request_id, document_id, request_status }.
check_extraction_status
Poll an extraction job by request_id.
Returns the job state: request_status is one of pending, processing, completed, failed, exception. When completed, results.data contains the extracted fields keyed exactly as defined in the template schema, and results.num_pages reports the pages processed. When failed, error describes what went wrong.
list_templates
List the extraction templates on your account (invoices, purchase orders, receipts, tax forms, custom layouts). Supports search_term and pagination via page_token / next_page_token. Returns template_id, template_title, and template_type per template.
get_schema
Fetch a template's field definitions — field name, type, description, and nested table columns — so an agent can generate a matching data model. Extraction results use exactly these field names.
create_template
Create a new extraction template (Workflow) from a title and field schema — agents can define extraction schemas on the fly instead of only using pre-built templates. See Create Workflow for the underlying REST endpoint and field-schema rules ("Workflow" and "Template" are used interchangeably in DocumentPro).
| Input | Type | Required | Description |
|---|---|---|---|
template_title | string | yes | Template name, max 300 characters. |
template_schema | object | yes | Field definitions: { "fields": [{ "name", "type", ... }] }. |
template_type | string | no | Free-text category, e.g. "invoice". |
Field rules: names use lowercase letters, digits, underscores, and spaces (max 50 characters, unique within the template); types are text, number, date, radio, checkbox, boolean, object, table; table and object fields must define subFields; no field may be marked required — every field must allow null. Call get_schema on an existing template first for a worked example.
Returns the created template: { template_id, template_title, template_type, template_schema }.
update_template
Replace a template's field schema and/or rename it. template_schema replaces the schema entirely, so fetch the current schema with get_schema before adding or changing fields.
| Input | Type | Required | Description |
|---|---|---|---|
template_id | string | yes | Template to update. |
template_schema | object | one of | New field definitions — same shape and rules as create_template. |
template_title | string | one of | New template name. |
Returns the updated template, same shape as create_template.
classify_document
Assign one of your labels to a document — use it to route mixed document streams to the right extraction template. Synchronous — no polling required. Calls the same classification pipeline as Classify Document / Run Classification.
| Input | Type | Required | Description |
|---|---|---|---|
classifier_id | string | one of | A saved classifier (see create_classifier). |
labels | array | one of | Inline labels, at least 2: [{ "label", "description" }]. |
document_id | string | one of | An already-uploaded document. |
file_url | string | one of | Publicly reachable URL of the document. |
file_base64 | string | one of | Inline base64 file content, max 7 MB decoded. Requires file_name. |
page_range | string | no | Classify using specific pages only, e.g. "1-3". |
query_model | string | no | Model override — inline labels only; saved classifiers use their own model. |
Provide the document as exactly one of document_id / file_url / file_base64, and the classifier as exactly one of classifier_id / labels.
Unlike the REST classify endpoints, classify_document does not require the document to be pre-processed — it enqueues OCR automatically and waits briefly. If OCR takes longer than a few seconds, the tool returns a DOCUMENT_NOT_READY error carrying the document_id; retry the same call with that document_id after about 15 seconds.
Returns { request_id, document_id, classifier_id, classification, confidence_scores, request_status, credits_used, num_pages, duration }.
create_classifier
Save a reusable classifier — see Create Classifier for the underlying REST endpoint. Use its classifier_id with classify_document to route documents consistently instead of repeating inline labels.
| Input | Type | Required | Description |
|---|---|---|---|
name | string | yes | Classifier name. |
labels | array | yes | At least 2 classes: [{ "label", "description" }]. |
classifier_type | string | no | "document" (default, one label per document) or "page" (labels each page). |
page_range | string | no | Default page range to classify on. |
Returns the created classifier: { classifier_id, name, classifier_type, labels, page_range, created_at, updated_at }.
list_classifiers
List the saved classifiers on this account, including their labels. See List Classifiers for the underlying REST endpoint. No parameters.
Returns { classifiers: [...] }.
list_supported_formats
Returns the accepted file formats: pdf, png, jpg/jpeg, tiff/tif, txt, doc, docx, html.
get_credit_balance
Check remaining credits before starting a batch job. Takes no parameters.
| Field | Description |
|---|---|
plan_type | Current subscription plan. |
plan_credits_remaining | Credits remaining in the current billing period. Resets on plan renewal. |
topup_credits_remaining | Purchased top-up credits. Never expire; drawn down after plan credits. |
total_credits_remaining | Plan + top-up credits — the total available before extraction/classification calls start failing with INSUFFICIENT_CREDITS. |
plan_end_date | When the current billing period ends and plan credits reset. |
Errors
Tools return structured errors, never stack traces:
{ "error_code": "NOT_FOUND", "message": "Template not found" }
| Code | Meaning |
|---|---|
UNAUTHORIZED | Missing or unknown API key. |
FORBIDDEN | The key does not have access to the requested resource. |
NOT_FOUND | Template or request id does not exist on this account. |
INVALID_INPUT | Bad arguments (e.g. both file_url and file_base64, unsupported format, file over the base64 limit, an invalid template or classifier schema). The message includes field-level detail so you can correct and retry. |
DOCUMENT_NOT_READY | classify_document only: the document is still being OCR'd. Retry with the document_id from the error message after about 15 seconds. |
INSUFFICIENT_CREDITS | Your account is out of credits for this operation. Not fixable by retrying — top up before trying again. |
SCHEMA_UNAVAILABLE | The template's stored schema cannot be rendered (rare legacy records). Choose a different template. |
PAGE_LIMIT_EXCEEDED | Document exceeds the page cap (100 pages, 300 for tax-flagged accounts). |
INTERNAL_ERROR | Something went wrong on our side — contact support if it persists. |
See Error Codes for details and the REST API's separate (non-matching) error vocabulary.
Notes
- MCP traffic is metered and rate-limited by the same usage plan as your REST API traffic. See Rate Limits & Polling for polling guidance on
check_extraction_status. - The MCP server calls the same extraction, classification, and template pipelines as the REST API (e.g.
POST /v1/extract,POST /v1/classify,POST /v1/templates) — results are identical for the same inputs. - Building on Replit or Lovable? See the quick-start pages: DocumentPro + Replit and DocumentPro + Lovable.