Publish a file that is already on disk
Most of what agents make is written to disk first: a report, a deck, a chart rendered to PNG. To publish it, the agent should not read the whole file back and paste it into a tool call. It asks myartefacts for a one-time upload link and sends the file with a single curl.
Why not just paste it
publish_artifact takes the file's contents as an argument. That is fine for a short note the agent has not saved anywhere. For a file on disk it is wasteful: a 300 KB HTML page has to pass through the conversation twice, once when the agent reads it and once when it writes it into the call. That spends context and time, and long outputs are where agents start trimming things they should not. Binary files are worse, since a PDF or PNG has to travel as base64, a third larger than the file itself.
create_upload_url sends only the details through the conversation. The file goes from disk to your library directly.
How it works
- The agent asks for a link. It calls
create_upload_url with the file name, and the same details it would give publish_artifact: title, project, summary, prompt, and slug or share when they apply. path says where the file is, if that differs from the name.
- It gets the link back, with a ready-made
curl command and the time it expires.
- It runs the command. No token goes in it: the link itself stands in for one.
- The file is published. curl prints the answer: the slug, the version, and the
library_url that opens it in your library.
The call, with the extension deciding how the file renders:
{
"filename": "q3-report.html",
"path": "./out/q3-report.html",
"title": "Q3 report",
"project": "Finance/Reports",
"summary": "Revenue, churn and runway for the third quarter."
}
And what comes back (the link carries a 48-character ticket, shortened here):
{
"upload_url": "https://myartefacts.com/api/uploads/TICKET",
"curl": "curl -sS -T './out/q3-report.html' 'https://myartefacts.com/api/uploads/TICKET'",
"expires_at": "2026-10-26T10:30:00+00:00",
"note": "Send the raw file with PUT (curl -T), or POST it as a multipart `file` field. The link works once, for 30 minutes."
}
The agent runs the curl exactly as given. The answer is the same artefact record any publish returns, abridged here:
{
"data": {
"slug": "q3-report",
"title": "Q3 report",
"kind": "HTML",
"project": "Finance/Reports",
"version": 1,
"share_url": null,
"library_url": "https://myartefacts.com/artefacts?open=q3-report"
}
}
The rules of the link
- One useOnce a file is published through it, the link is spent. Ask again for the next file.
- Thirty minutesAn unused link expires half an hour after it was made.
- Up to 20 MBThe same limit as every other way of publishing.
- Tied to its tokenThe upload is recorded as the agent that asked. Revoke that token and its open links stop working too.
The link accepts the raw file as a PUT, which is what curl -T sends, or a multipart POST with a file field. It answers 201 for a new artefact and 200 for a new version. A link that has expired or was already used answers 410 with a message telling the agent to ask for a new one. An upload that is turned away, because it was empty or over 20 MB, does not spend the link: fix the file and send it again within the half hour.
Sending a new version
Pass the slug of an artefact that already exists and the upload becomes its next version, at the same URL, so every link you have handed out shows the new file. Update an artefact without breaking its link covers what changes and what stays.
Choose the project before uploading
If the project you name does not exist yet, the answer from create_upload_url carries a project_note saying the upload will start one, and naming any similar projects you already have. That arrives before the file moves, while it is still cheap to ask for a new link with the right project. Agents are told to call list_projects first; Projects: how agents file their work explains why.
Without MCP
An agent with a shell and a token but no MCP can publish a file on disk just as directly through the HTTP API, as a multipart upload:
curl -s https://myartefacts.com/api/artifacts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json" \
-F file=@./out/q3-report.html \
-F title="Q3 report" \
-F project="Finance/Reports"
Here the token is in the command, so the agent should read it from an environment variable rather than writing it out.
Getting your agent to do it
You rarely need to ask. The server's instructions tell every connected agent to use create_upload_url for anything on disk, and to keep publish_artifact for short text it has not saved. If an agent pastes a big file anyway, one line puts it right: use create_upload_url and run the curl it gives you.
Sandboxed shells. Some agents run commands in a sandbox with the network switched off. If the curl fails to connect, approve the command when the agent asks, or allow network access for that session, then run it again on the same link.
Not connected yet? Start with Claude Code or Codex, Cursor and other MCP clients.