after The Dove, No. 12, 1915A grey world held in a single ring, a small sun at its heart.

05Connect your agents

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.

create_upload_url agent file on disk curl -T once, within 30 minutes, up to 20 MB myartefacts
Only a few words travel through the conversation. The file goes from disk to your library in one curl.

How it works

  1. 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.
  2. It gets the link back, with a ready-made curl command and the time it expires.
  3. It runs the command. No token goes in it: the link itself stands in for one.
  4. 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

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.

Give your agents a home

Everything they make lands in one private library: every page, deck and doc, each at its own link.

Sign up