create_pdf
Convert a Microsoft Office document (.docx, .xlsx, .pptx) or inline markdown into a PDF, then deliver it as an email attachment or save it to OneDrive.
What it does
create_pdf is a single agent tool that dispatches to two pure converters:
- Office formats (
.docx,.xlsx,.pptx,.mdalready in OneDrive) are converted via Microsoft Graph's built-in?format=pdfendpoint. - Inline markdown is rendered with the
md-to-pdfheadless-Chromium pipeline using one of the bundled themes (default,business-case).
The tool can store the PDF as a generated asset (the default), return it inline as base64, write it to OneDrive, or do both of the last two. Cross-tenant isolation is enforced by construction: the tool always uses the caller's delegated Graph token and the caller's tenant for OneDrive writes, and generated assets are stored under the caller's tenant; no tenantId parameter is accepted.
When to pick it
Use create_pdf when an agent needs to:
- Produce a PDF from an Office document already stored in OneDrive or SharePoint.
- Render an agent-authored markdown report (status update, business case, daily brief) into a polished, themed PDF that can be attached to email, posted to a project, or saved to OneDrive.
- Convert a small batch of files in-place without exposing the conversion mechanics to the caller.
It is not the right tool for:
- OpenDocument or legacy Office formats (
.odt,.doc,.rtf). - Excel sheet-selection or fit-to-page rendering controls.
- PDF post-processing (watermarks, page numbers, merging documents).
- Inline non-markdown bytes - pass
.docx/.xlsx/.pptxthrough OneDrive (source.graphItem) instead.
Input examples
The source field is a discriminated union: provide exactly one of source.graphItem or source.inline.
Source: graphItem (Office format already in OneDrive)
{
"source": {
"graphItem": {
"driveId": "b!abc...",
"itemId": "01XYZ..."
}
},
"output": "onedrive",
"destination": {
"folderPath": "/Reports/2026-Q1"
}
}
When output is "onedrive" and destination.folderPath / destination.filename are omitted, the PDF is written next to the source item with the same base filename plus .pdf.
Source: inline markdown
{
"source": {
"inline": {
"format": "markdown",
"content": "# Q1 Status\n\nProgress against goals...",
"filename": "q1-status.md"
}
},
"theme": "business-case",
"output": "onedrive",
"destination": {
"folderPath": "/Outermind Artifacts/PDFs"
}
}
theme is honored for inline markdown only; it is ignored on the graphItem path. Themes are CSS files keyed by name (currently default and business-case).
Output: asset (default, deliverable as an email attachment)
{
"source": {
"inline": {
"format": "markdown",
"content": "# Website Redesign Proposal\n\nPrepared for ...",
"filename": "proposal"
}
}
}
output defaults to "asset". The PDF is stored as a private, tenant-scoped generated asset and the response carries asset_id, url, content_type, and filename, with no onedrive block. The PDF bytes themselves are never returned in the response.
This is the mode that lets an agent actually send someone a PDF. The agent passes the returned asset_id to the attachments parameter of respond or send_to, and the bytes travel with the outgoing email as a real file attachment. Two things to know:
- The
urlis an authenticated in-app link. It requires a signed-in Outermind session, so it must not be pasted into email body text - an external recipient gets a 401. - The delivered attachment is named from the asset id, not from
filename. Thefilenamefield is an echo for the agent's own reference.
Output: inline (alias for asset, no OneDrive write)
{
"source": {
"inline": {
"format": "markdown",
"content": "# Daily Brief\n\n...",
"filename": "daily-brief.md"
}
},
"output": "inline"
}
"inline" behaves exactly like "asset": the response carries asset_id, url, content_type, and filename, and no onedrive block. It used to return the encoded PDF as pdfBase64, which put a multi-megabyte string into the agent's own conversation and could exhaust its context window; the bytes now travel on the asset rail instead.
Output: both (save an asset AND save to OneDrive)
{
"source": {
"graphItem": {
"driveId": "b!abc...",
"itemId": "01XYZ..."
}
},
"output": "both",
"destination": {
"folderPath": "/Reports/2026-Q1",
"filename": "summary.pdf"
}
}
The response carries both the asset fields (asset_id, url, content_type, filename) and an onedrive block (driveId, itemId, webUrl).
Output: onedrive (save only)
{
"source": {
"graphItem": {
"driveId": "b!abc...",
"itemId": "01XYZ..."
}
},
"output": "onedrive"
}
The response carries an onedrive block and no asset fields. "onedrive" needs a target drive: with a graphItem source it defaults to the source item's own drive, but an inline markdown source has no drive to fall back on, so destination.driveId is required there.
Error codes the agent can react to
The tool returns a structured error envelope on failure. Each error declares retryable so the agent can decide between immediate retry, escalation, or a different approach.
| Code | Meaning | Retryable |
|---|---|---|
unsupported_format | The graphItem source is not a format Graph can convert (e.g., .txt, .zip). | No |
graph_conversion_failed | Microsoft Graph returned a server error during conversion. One automatic retry has already been attempted. | Yes |
render_failed | The markdown render pipeline failed or timed out. | Yes (re-render may succeed; reduce input size if persistent) |
source_not_found | The graphItem driveId/itemId does not exist or the caller cannot access it (404 or 403). Often a permissions problem rather than a missing file. | No |
input_too_large | Inline markdown exceeded 5 MB, or the source graphItem exceeded 50 MB. | No |
destination_unavailable | The output target could not be reached: on "onedrive"/"both" no target drive was resolvable, or the drive is offline / over quota / permission-denied; on "asset" the generated-asset store rejected the write. | Yes (No when the OneDrive target simply was not supplied) |
Agent guidance for common cases:
source_not_found: surface the failure to the user with a request to verify the file path or share permissions; do not retry blindly.input_too_large: shrink the markdown (trim verbose sections, drop large embedded images) or split the source document; retry once with the smaller input.destination_unavailable: fall back tooutput: "asset"to get anasset_idthat can be attached to a reply, or tooutput: "inline"to return the base64 PDF, then ask the user where to save it.
Limits
| Limit | Value | Where enforced |
|---|---|---|
| Inline markdown input size | 5 MB | markdown-pdf converter |
Source file size (graphItem) | 50 MB (pre-checked via Graph metadata) | graph-format-pdf converter |
| Markdown render timeout | 30 seconds | markdown-pdf converter |
| Graph 429 retry | One automatic retry honoring Retry-After | graph-format-pdf converter |
Telemetry: every call emits one structured tool-call log entry with { tool, durationMs, sourceKind, sourceFormat, outputMode, byteSize, ok, errorCode? }.
Default availability
create_pdf is available to every agent, with no per-agent assignment. It is one of the platform's built-in tools, alongside create_spreadsheet, create_document and create_presentation: the platform supplies it directly to each agent rather than an administrator assigning it, so there is no per-agent switch to flip and nothing for an agent to request. (One organization-wide permission does still apply to create_pdf; see below.) This applies to your AI Chief of Staff, every Personal Assistant, every specialist agent and every subject matter expert alike.
Because it is built in rather than assigned, it does not appear in an agent's tool assignment panel and cannot be withheld from an individual agent.
create_pdf also still appears in the Media & Document Generation tool group (which absorbed the former Document Conversion group). That listing is what lets an agent discover the tool by searching its capabilities; it is not a permission.
One thing an administrator does still control: create_pdf can read source documents from, and write finished PDFs back to, SharePoint and OneDrive, so it is covered by your organization's SharePoint and OneDrive document permission. That permission is checked once per tool rather than per request, so until it is granted agents are not offered create_pdf at all - including for Markdown-only requests that would never touch SharePoint. The other three built-in document tools (create_spreadsheet, create_document, create_presentation) are not covered by it and are available either way.
Related tools
create_spreadsheet- author a new.xlsxworkbook, delivered through the same generated-asset rail.create_document- author a new.docxWord document from Markdown, on the same rail.create_presentation- author a new.pptxslide deck from structured slide data, on the same rail.save_file_to_onedrive- generic OneDrive write for non-PDF artifacts.link_artifact_to_project- record the resulting PDF on a CAIOO project page.