Skip to main content
Microsoft Agent Framework is Microsoft’s open-source SDK for building AI agents in Python and .NET. Unlike end-user AI tools that add the Transform MCP server through a settings screen, Microsoft Agent Framework connects to it from code: you load the Transform MCP server’s tools as agent tools and hand them to any Microsoft Agent Framework 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.

Requirements

Before you begin, you must have the following:
  • For Python: Python 3.10 or later on your local development machine. To check, in your terminal, run python --version or python3 --version. Install Python.
  • For .NET: the .NET 8.0 SDK or later on your local development machine. To check, in your terminal, run dotnet --version. Install .NET.
  • An Unstructured API key, which the Transform MCP server uses as a bearer token. Get an API key.
  • An OpenAI API key, or an Azure OpenAI resource, for the agent’s underlying chat model.

Install the packages

In your terminal, install the Microsoft Agent Framework packages and, for .NET, the Model Context Protocol SDK:
These SDKs are in active development, and their APIs change between releases. The versions shown here are the versions this guide was verified against. If you install different versions, check the Microsoft Agent Framework release notes for API changes.

Connect to the Transform MCP server

The Transform MCP server speaks the streamable HTTP transport and authenticates with your Unstructured API key sent as a bearer token. Store your key in an environment variable rather than hard-coding it:
The server requires the Authorization header on every request, including the initial initialize handshake. Set the header on the HTTP client or transport itself, as follows:
In Python, do not use the header_provider parameter as the only way to send the bearer token. header_provider injects headers only during tool calls, so the connection’s initialize handshake goes out unauthenticated and the server rejects it. Pass an httpx.AsyncClient with default headers through http_client instead, as shown above.

Add local file helpers for uploads and downloads

Transform’s job lifecycle mixes MCP tool calls with two plain HTTP requests that are not MCP calls: an HTTP PUT of the raw file bytes to a pre-signed upload_url, and an HTTP GET of the finished output from a pre-signed download_url. An agent cannot perform raw HTTP requests through MCP tools alone. To close that gap, the full examples in the next section register three small local functions as additional agent tools:
  • describe_local_file: Returns a file’s filename, content type, and exact size in bytes, which request_file_upload_url requires.
  • upload_local_file: Sends the file bytes to the pre-signed upload_url with an HTTP PUT.
  • download_text: Retrieves the finished Markdown from the pre-signed download_url with an HTTP GET.
Pre-signed URLs carry their own credentials in the URL itself. The helpers must not send the Authorization header on these two requests, or the storage service rejects them.

Use the tools in an agent

The following example builds an agent that can drive the full Transform job lifecycle. The agent requests an upload URL, uploads the file through the local helper, starts the transform, polls for status, and downloads the Markdown output:

Parse your source files

Parsing requests have the following limits:
  • Each file must be of a supported file type.
  • Each file must be 50 MB or less in size.
  • Each request must have 10 files or fewer.
  • Only 5 requests can be running at a time.
The Transform MCP server is designed to report these limits back to the agent through its tool responses. Because of this, your agent should notify you whenever it encounters a file that exceeds 50 MB in size, and it should formulate strategies to send requests that are 10 files or fewer and not cause more than 5 requests to be running at a time. You can reinforce this behavior in your agent’s system prompt, as the examples above do for the file size limit.

Run the agent

The examples default to OpenAI as the chat model provider. Set your OpenAI key and model, place any PDF that is 50 MB or smaller at ./sample.pdf, and run the program:
The agent works through the tool sequence and prints a summary such as the following. Transforms take from about 10 seconds to several minutes, depending on page count:

Use Azure OpenAI as the chat model provider

To use Azure OpenAI instead of OpenAI, keep the Transform MCP connection code the same and change only the chat model configuration:

Troubleshooting

  • 401 Unauthorized or an invalid_token error on connect. Confirm the UNSTRUCTURED_API_KEY environment variable is set and that the Authorization header is formatted as Bearer <your-unstructured-api-key>. In Python, also confirm the header is set on the httpx.AsyncClient passed through http_client, not only through header_provider.
  • Session terminated or 404 when connecting. Verify the server URL is exactly https://mcp.transform.unstructured.io, with no path appended.
  • The upload or download request is rejected. The upload_url and download_url values are pre-signed. Send those two requests without the Authorization header.
  • The agent reports the job is still running. Transforms take from about 10 seconds to several minutes by page count. The agent keeps polling check_transform_status until the status is COMPLETED.
  • A compile or import error on the SDK APIs. These SDKs are in active development. Install the exact package versions pinned in this guide, or update the code to the installed versions’ APIs.

Next steps

  • Control Transform file parsing output: Control how the Unstructured Transform MCP server instructs Transform to partition, enrich, chunk, and embed the data based on your files.
  • Control Transform generated sample code: Control how the Unstructured Transform MCP server generates sample curl or Python code that demonstrates how to use Transform to partition, enrich, chunk, and embed the data based on your files.

Questions? Need help?