Attach files to documents¶
Outcome¶
Screenshots, screen recordings, PDFs, Office files and ZIP archives live in the document itself, not on another site's CDN. Pictures and videos show in the text — videos play in place — and every other file is a download link. Readers of a public link see the attachments of the version they are shown.
Before you begin¶
- You need the
memberrole or higher to attach files. Viewers see them. - One file is at most 120 MB. A project stores up to 20 GB of attachments (the operator can change this); the same file attached twice is stored once.
- AI agents attach files through MCP — see "Let an AI agent attach a file" below.
- Every file is checked by the server's own antivirus before it is stored; the file is not sent to any outside service. A file with malware is not attached.
Attach a file in the editor¶
- Open the document and select Edit.
- Paste a file into the text (Ctrl+V / ⌘V) or drop it there.
- A placeholder holds its place while it uploads; for a large file the line under the text shows how far the upload got. Saving waits until it is done.
- When the upload finishes, the placeholder becomes the reference:
for a picture or a video,[name](attachment://…)for any other file. - Select Save draft.
The preview shows pictures, plays videos and links files the way the document will.
What you can attach¶
| Kind | Types | Shown as |
|---|---|---|
| Picture | PNG, JPEG, GIF, WebP | the picture |
| Video | MP4 (.mp4, .m4v), MOV, WebM |
a video player |
| Document | PDF, Word (.docx), Excel (.xlsx), PowerPoint (.pptx) |
a download link |
| Archive | ZIP | a download link |
Threadory decides the type from the file's contents, not from its name:
- the name must match the contents — a picture named
.pdf, or an MP4 named.mov, is refused; - SVG, HTML and text files (CSV, TXT) are never accepted;
- Office files with macros (
.xlsm,.docm) are refused, also when renamed to.zip; - a video plays only if your browser knows its codec: H.264 MP4 plays
everywhere, an HEVC
.movfrom an iPhone may not play in Chrome.
Let an AI agent attach a file¶
An agent connected through MCP does not send the file through the conversation — that would cost its context and fails for anything but tiny files. Instead:
- The agent calls
kb_prepare_attachment_uploadwith the document and the file name, and gets a one-time upload URL. - It uploads the file with one command, for example
curl -sS --fail-with-body -T screenshot.png '<upload_url>'. The URL works once and for 30 minutes; it needs no other sign-in, so it must stay private. - It calls
kb_commit_attachment_uploadand puts the reference it gets into the document.
If the agent cannot run commands, it gives you a link instead — see the next section.
Upload a file for an agent¶
- Open the link the agent gave you (
…/attachments/upload/…). You are asked to sign in if you are not. - Choose the file, or drop it on the page. A progress bar shows the upload.
- When it is done, go back to the agent. If you started the agent's session yourself, the page attaches the file at once and shows its reference; either way the agent finishes the job.
The page works only for members of the document's project, and only until the link expires (30 minutes).
Troubleshooting¶
| What you see | Why | What to do |
|---|---|---|
| "The file is larger than 120 MB." | The cap per file | Compress or split the file |
| "Only PNG, JPEG, … files can be attached." | The contents are not one of the types above | Export to a supported type |
| "The file's name doesn't match its contents" | The extension names another type | Rename the file to its real type |
| "This project's storage for attachments is full." | The project's quota is used up | Ask an admin to prune unused attachments, or the operator to raise the quota |
| "This upload link has expired." / "was already used." | Upload links work once, for 30 minutes | Ask the agent for a new one |
The agent reports too_many_open_uploads |
At most 5 unfinished uploads per person and 20 per project | Let the agent finish (commit) the uploads it started, or wait 30 minutes for them to expire |
"The server is receiving too many files right now" (or the agent's upload gets 429 too_many_uploads) |
Only a few files are received at once, of any size — per person in the editor, per address for upload links, and for the whole server | Try again in a few seconds (the editor retries by itself for a minute); nothing was stored. On the upload page just pick the file again; an agent repeats its upload with the same link |
| "The antivirus found malware in this file, so it was not attached." | The server's antivirus matched a known threat (an upload link is used up by it) | Do not open the file; get a clean copy from its source. If you are sure it is clean, tell your operator — it may be a false positive |
| "The file could not be checked by the antivirus — an encrypted (password-protected) archive or PDF, or an archive that is too large to check" | The antivirus cannot look inside an encrypted file, and stops at a size limit when unpacking an archive; a file it cannot check whole is not attached | Send the file without a password, or split a very large archive into smaller ones. A PDF that opens without a password is fine. A ZIP or presentation holding a lot of photos or video (more than about 60 MB of them) takes the antivirus too long to check: attach the videos and photos directly — on their own they are checked in seconds |
| "The file was not attached: the antivirus check is unavailable right now." | The antivirus did not answer, so nothing was stored — files are never kept unchecked | Try again in a few minutes. A file sent through an upload link stays received: the agent attaches it once the check works again |
| The upload page says "Checking … The antivirus check of a large file can take a few minutes." | The answer did not arrive in time; the page now reads the upload's state instead | Wait on the page: it shows the attachment, or why it was refused. After about 5 minutes it hands over to the agent |
| A video shows a player but does not play | The browser does not support its codec | Convert it to H.264 MP4 |