Skip to main content
PraisonAI is an open-source framework for building multi-agent AI systems in a few lines of Python. Like other agent frameworks, it connects to the Transform MCP server from agent code: you declare the server as an MCP client and hand its tools to an agent. Because Transform is a hosted remote MCP server, there is nothing to install or run locally. You point the client at the server URL and authenticate with your Unstructured API key. PraisonAI’s MCP class connects to a remote server over streamable HTTP and carries your Unstructured API key as an Authorization: Bearer header on every request, including the initial handshake.

Requirements

Before you begin, you must have the following:
  • Python 3.10 or later on your local development machine. To check, in your terminal, run python --version or python3 --version. Install Python.
  • praisonaiagents 1.6.154 or later. Two fixes matter here: 1.6.152 added the remote streamable-HTTP MCP fix, without which PraisonAI cannot connect to a remote MCP server at all, and 1.6.154 made the agent’s loop guard result-aware. Before 1.6.154, the loop guard counted status polls as “no progress” and halted a transform after eight tool calls, so a multi-minute job never reached an answer. See the PraisonAI releases.
  • An Unstructured API key, which the Transform MCP server uses as a bearer token. Get an API key.
  • An API key for the agent’s underlying model, for example an OpenAI API key.

Install the packages

In your terminal, install PraisonAI with the mcp extra:

Connect to the Transform MCP server

Store your keys in environment variables rather than hard-coding them:
In your agent code, declare the Transform MCP server with the MCP class and hand it to an agent. The headers setting attaches the Authorization: Bearer header to every request, so the handshake and the tool calls are both authenticated. Transforms run as asynchronous jobs that take from about 30 seconds to a few minutes, and two settings keep the agent from giving up before a job finishes. Both are explained under Pace the polling loop below:
Use the server URL exactly as shown. Do not add /mcp or /sse to the end of the URL.

Pace the polling loop

The two additions above are what make a multi-minute transform complete. Without them the agent connects and calls the tools, but never reaches an answer:
  • wait_seconds, passed alongside the MCP tools. PraisonAI has no built-in pacing, so an agent left to itself polls check_job_status every couple of seconds and then concludes the job is taking too long and stops, while the transform is still running. Unpacking the MCP tools with *transform_tools lets you add this local function to the same list. The instruction to call it between status checks matters as much as the tool itself.
  • ExecutionConfig(max_tool_calls_per_turn=100). PraisonAI caps a turn at 10 tool calls by default, which a paced polling loop passes well before a job finishes. The cap then ends the turn with “Tool call limit reached (10 calls)” rather than an answer.

Run the agent

Ask the agent to parse a document and answer a question about it:
Transforming a document is asynchronous: the agent starts a job with start_transform_job, waits with wait_seconds, polls check_job_status until it is complete, then retrieves the output with get_job_results. Large or scanned documents can take a few minutes. The Transform tools the agent uses for this flow are request_file_upload_url, start_transform_job, check_job_status, and get_job_results, alongside the local wait_seconds function.

Extract structured data

To pull specific fields out of a document rather than convert the whole document, ask the agent for an extraction:
The agent parses the file first, then extracts from the parsed element JSON using suggest_extraction_schema_for_file (when you have not supplied a schema) and start_extraction_job, polling with the same check_job_status and get_job_results tools. Extraction runs on the element JSON that a parse produces rather than on the raw file, so it always follows a transform job, and chaining the two takes longer than a parse alone. Results arrive as JSON matching the schema, wrapped with the source filename and the element JSON reference they were taken from. Extraction can only surface what the parse captured, so ask for a higher-fidelity parse if a first attempt comes back sparse. For prompt patterns, see Structured data extraction.

Next steps

Questions? Need help?