Skip to main content

MCP Server

Unstract hosts a Model Context Protocol (MCP) server alongside every API deployment, so coding agents and other MCP clients can run document extraction as tool calls instead of building HTTP requests by hand.

The server runs inside Unstract itself — there is nothing to install or host, and no new credential to create. An MCP session is scoped to exactly one API deployment and authenticates with the API key that deployment already uses.

Looking for the local Docker tool?

The older stdio server distributed as the unstract/mcp-server Docker image is documented separately under Local MCP Server (stdio). The server described on this page needs no local process.

What you need

  • An API deployment. See API Deployments if you have not created one yet.
  • That deployment's API key, available from the API Deployment tab in the same place you manage keys for REST calls.
  • An MCP client that connects over HTTP and can send an Authorization header — Claude Code, for example.

Endpoint

The MCP endpoint sits directly alongside the deployment's REST endpoint, with /mcp appended:

POST /deployment/api/<org_name>/<api_name>/      # REST
POST /deployment/api/<org_name>/<api_name>/mcp # MCP

Both are the same deployment reached two ways. <org_name> and <api_name> are exactly the values already in your deployment's REST URL, so the simplest way to build the MCP URL is to copy the REST one and add mcp.

Authentication

Pass the deployment's existing API key as a bearer token:

Authorization: Bearer <api_key>

This is the same key used for REST execution, managed from the same screen. There is no separate MCP credential to create or revoke, and revoking the key closes both surfaces at once.

The key goes in a header, never in the URL

There is deliberately no endpoint that accepts the API key as part of the path. A key in a URL reaches web-server and application access logs, monitoring traces and any proxy in between — places a header never reaches — and the MCP specification requires the Authorization header on every authenticated request. If your client cannot set headers, it cannot connect to this server.

Every authentication failure answers 401 with no detail, whatever the cause, so the endpoint cannot be used to discover which deployment names exist.

Connecting

Claude Code

claude mcp add --transport http unstract \
https://us-central.unstract.com/deployment/api/<org_name>/<api_name>/mcp \
--header "Authorization: Bearer <api_key>"

Other clients

Point the client at the same URL over HTTP transport, with the Authorization header set. Many clients express this as JSON along these lines — check your client's own documentation for the exact key names it expects:

{
"mcpServers": {
"unstract": {
"type": "http",
"url": "https://us-central.unstract.com/deployment/api/<org_name>/<api_name>/mcp",
"headers": {
"Authorization": "Bearer <api_key>"
}
}
}
}

Replace the host with your own — for example https://eu-central.unstract.com on the EU region, or your own domain for an on-premise installation.

Tools

ToolPurpose
readMeFirstOrientation for the agent, built from the live deployment. Worth calling first.
getApiInfoName, description, workflow and active state of the connected deployment.
extractDocumentRun the deployment's extraction workflow over one or more documents. Consumes your extraction quota.
getExecutionStatusFetch the result of an extraction started by extractDocument.

The deployment fixes the prompts and the output schema, so an agent supplies documents rather than instructions. To change what is extracted, change the Prompt Studio project behind the deployment.

extractDocument arguments

ArgumentTypeDefaultDescription
document_urlsarray of stringsRequired. HTTPS URLs of the documents to extract. At most 32 per call. See Supplying documents below.
timeoutinteger30Seconds to wait for extraction to finish before returning a pending result. Ranges from -1 to 300; use -1 to return immediately and poll.
include_metadatabooleanfalseInclude extraction metadata in the result.
include_metricsbooleanfalseInclude token and cost metrics in the result.
include_extracted_textbooleanfalseInclude the full raw text of each document alongside the structured output. This can be very large.
tagsarray of stringsTags to record against the execution. Currently limited to 1 tag, which must start with a letter and contain only letters, numbers, underscores and hyphens.
llm_profile_idstringUUID of an LLM profile to override the deployment's default.

The default timeout of 30 seconds is shorter than the REST API's, deliberately: holding an MCP call open for several minutes looks like a hang to an agent, so the server returns early and lets the agent poll instead.

getExecutionStatus arguments

ArgumentTypeDefaultDescription
execution_idstringRequired. The execution_id returned by a previous extractDocument call.
include_metadatabooleanfalseInclude extraction metadata in the result.
include_metricsbooleanfalseInclude token and cost metrics in the result.
include_extracted_textbooleanfalseInclude the full raw text of each document.

Supplying documents

Documents are not uploaded through the MCP call. You pass URLs, and Unstract fetches each document server-side — the same mechanism the REST API uses for presigned_urls:

  • The URL must use HTTPS.
  • The host must be an AWS S3 endpoint. Links to any other host are rejected, so upload the document to S3 first if it is not already there.
  • For a private object, pass a pre-signed URL. This is the usual case. An object that is already publicly readable needs no signature.

The maximum file size per URL is configurable by your administrator. See API Execution for the full set of rules, which the MCP server shares with the REST surface.

How an extraction completes

Extraction is asynchronous. A typical exchange runs:

  1. extractDocument is called with one or more document URLs.
  2. If extraction finishes within timeout, the response carries execution_status: COMPLETED and the result — nothing further is needed.
  3. Otherwise the response carries execution_status: PENDING and an execution_id.
  4. The agent polls getExecutionStatus with that execution_id, pausing a few seconds between calls, until the status is COMPLETED or ERROR.

An execution_id is always returned, so a pending extraction is never lost. Never retry an extractDocument call that already returned an execution_id — that starts a second extraction and consumes quota again. Poll instead.

A completed result can be read only once

Reading a COMPLETED execution acknowledges it, and the result is not retrievable afterwards. A second getExecutionStatus call for the same execution_id returns a message saying the result was already acknowledged, not the result. This is existing API deployment behaviour, which the REST surface reports as HTTP 406; it is not specific to MCP. If an agent needs the data again, it must run a new extraction.

Limits and errors

extractDocument consumes your organization's extraction quota and is subject to the same organization-level rate limit as REST execution. When that limit is reached, the tool reports how much is in use and asks the caller to retry once running extractions finish.

Problems an agent can act on — a bad argument, an inactive deployment, a rate limit — come back as readable tool errors that the agent can correct and retry. Unexpected failures are logged server-side and reported generically, without internal detail; if one persists, an administrator can correlate it by deployment name and timestamp. Free-form error text is passed through redaction before it leaves the server, so a failing connector cannot leak the connection string it tried.

If the deployment is inactive, extractDocument refuses with a message saying so. Activate it in Unstract and retry.

Protocol details

  • Transport: Streamable HTTP. Every tool call is a request/response pair.
  • Protocol revision: 2025-06-18. A client that asks for 2024-11-05 is also accepted — the parts of the protocol used here are identical across the two revisions.
  • Methods: initialize, tools/list, tools/call and ping.
  • GET on the endpoint answers 405 Method Not Allowed. Under Streamable HTTP a GET opens a server-to-client event stream, and this server has nothing to stream, so it declines. This is expected and is not a misconfiguration.

Troubleshooting

What you seeLikely cause
401 on connectWrong or revoked API key, wrong <org_name>/<api_name>, or the key belongs to a different deployment. All auth failures look identical by design.
405 when testing in a browserA browser issues GET. The endpoint accepts POST only; use an MCP client.
Client cannot connect at allThe client must support HTTP transport and custom headers. A stdio-only client cannot reach this server — see Local MCP Server (stdio).
A document URL is rejectedThe URL is not HTTPS, or its host is not an AWS S3 endpoint. Upload to S3 and pass a pre-signed URL.
The deployment is reported as not activeActivate the deployment in the API Deployment tab.
getExecutionStatus says the result was already acknowledgedThe result was already read once and is gone. Run a new extraction.