Reference

import_screenshot

Turn attachments, URLs or local paths into account-scoped refs the render tools accept.

View as Markdown

What it does

  • Writes
  • No account needed

How screenshots that exist only in this conversation get into ShotOps. One call takes several sources in screenshots — PNG/JPEG URLs, or local file paths on the stdio server — and hands each back as a private ref. The bytes move server to server, so they never enter model context. Results come back one per entry in input order, and a failed entry reports its own error without cancelling the rest. A ChatGPT attachment is the exception: it arrives as the top-level file parameter, which carries one attachment, so N attached screenshots are N calls.

You can ask: “Import these two Tidebook screenshot URLs for later rendering.”

The published schema accepts any shape inside screenshots so a two-source entry comes back as a sentence instead of three stacked union errors. The real element shapes are below.

Input

  • screenshotsarrayoptionalat least 1 itemat most 10 items

    The screenshots to import, 1–10, in the order you want them back. Each entry names EXACTLY ONE source: { "url": "https://…" } (this server fetches a PNG or JPEG, converts JPEG to PNG, and stores it under your account), { "file": { "download_url": "…", "file_id": "…" } } (a ChatGPT attachment descriptor), or (local stdio server only) { "path": "/abs/shot.png" }. Add "name" to any entry to keep its original filename. One result per entry, in this exact order — a failed entry reports its own error and never cancels the others. In ChatGPT, an attachment arrives as the top-level file parameter instead, one attachment per call — batch URL sources here and import each attachment in its own call; one call may carry both.

    each item

    any

    The published schema does not constrain this element, on purpose — a malformed entry comes back as a sentence instead of a stacked union error. What the server re-validates against is below.

  • fileobjectoptional

    A PNG or JPEG attached by the user in ChatGPT — the top-level ChatGPT file parameter. It holds exactly ONE attachment, so N attached screenshots are N import_screenshot calls; collect a ref from each before rendering. JPEGs are converted to PNG before storage. Other clients put their sources in screenshots instead.

    • download_urlstringrequired

      Short-lived HTTPS download URL supplied by ChatGPT.

    • file_idstringrequired

      ChatGPT file identifier.

    • mime_typestringoptional

      File MIME type supplied by ChatGPT.

    • file_namestringoptionalat most 200 characters

      Original attachment filename, when available.

  • namestringoptionalat most 200 characters

    Override the filename stored in the returned ref for the top-level file. Defaults to file.file_name. Entries in screenshots carry their own "name".

  • localestringoptional

    Optional bookkeeping tag for the App Store locale these screenshots belong to.

What the server actually accepts

The published schema above deliberately accepts a wider shape for screenshots, file, so a malformed entry comes back as a sentence rather than a stack of union errors. The server re-validates against these shapes and refuses anything else.

  • screenshotsarrayoptionalat least 1 itemat most 10 items

    The screenshots to import, 1–10, in the order you want them back. Each entry names EXACTLY ONE source: { "url": "https://…" } (this server fetches a PNG or JPEG, converts JPEG to PNG, and stores it under your account), { "file": { "download_url": "…", "file_id": "…" } } (a ChatGPT attachment descriptor), or (local stdio server only) { "path": "/abs/shot.png" }. Add "name" to any entry to keep its original filename. One result per entry, in this exact order — a failed entry reports its own error and never cancels the others. In ChatGPT, an attachment arrives as the top-level file parameter instead, one attachment per call — batch URL sources here and import each attachment in its own call; one call may carry both.

    each item

    one of 3 shapes

    1url

    • urlstringrequiredat least 1 character

      An https URL to a PNG or JPEG. This server fetches it and converts JPEG to PNG — https only, no redirects, 20MB cap.

    • namestringoptionalat most 200 characters

      The screenshot's original filename, stored in the returned ref (e.g. "03_stats.png").

    2file

    A ChatGPT attachment descriptor: { "file": { "download_url": "…", "file_id": "…" } }.

    • fileobjectrequired

      • download_urlstringrequiredformat uri

        Short-lived HTTPS download URL supplied by ChatGPT.

      • file_idstringrequiredat least 1 character

        ChatGPT file identifier.

      • mime_typestringoptional

        File MIME type supplied by ChatGPT.

      • file_namestringoptionalat most 200 characters

        Original attachment filename, when available.

    • namestringoptionalat most 200 characters

      The screenshot's original filename, stored in the returned ref (e.g. "03_stats.png").

    3path

    • pathstringrequiredat least 1 character

      A local filesystem path to a PNG, read straight off disk — ONLY on the local stdio server (npx shotops-mcp); the hosted server rejects it.

    • namestringoptionalat most 200 characters

      The screenshot's original filename, stored in the returned ref (e.g. "03_stats.png").

  • fileobjectoptional

    • download_urlstringrequiredformat uri

      Short-lived HTTPS download URL supplied by ChatGPT.

    • file_idstringrequiredat least 1 character

      ChatGPT file identifier.

    • mime_typestringoptional

      File MIME type supplied by ChatGPT.

    • file_namestringoptionalat most 200 characters

      Original attachment filename, when available.

Result

  • okbooleanoptional

  • countintegeroptionalmin 0

  • screenshotsarrayoptional

    each item

    object

    • okbooleanrequired

    • sourcestringrequired

      one ofurlfilepath

    • namestringoptional

    • refstringoptional

    • urlstringoptional

    • pathstringoptional

    • sizeintegeroptionalmin 0

    • errorstringoptional

  • instructionsstringoptional

  • disclosureobjectoptional

    Stated because this call moved caller bytes into ShotOps storage. Relay it before or with the result; do not paraphrase the retention window.

    • movesstringrequired

      The bytes that left the caller’s control, in plain words.

    • whystringrequired

      What the move buys — never a restatement of the mechanism.

    • retentionDaysintegerrequiredgreater than 0

      How long ShotOps keeps it without an explicit retaining action. Read from the retention policy, never typed.

    • retainedBystringrequired

      The explicit action that keeps it past that window.

    • statementstringrequired

      The same four facts as one sentence, safe to relay verbatim.

Example

That request maps to this call:

{
  "name": "import_screenshot",
  "arguments": {
    "screenshots": [
      {
        "url": "https://example.com/tidebook/01-today.png",
        "name": "01-today.png"
      },
      {
        "url": "https://example.com/tidebook/02-forecast.png",
        "name": "02-forecast.png"
      }
    ]
  }
}

One result per entry, in the order you sent them, each with a ref or its own error.

Access and cost

  • One of the few tools a hosted caller may use with no account at all — getting your own screenshots in is part of the free taste.
  • Free. Importing spends no cloud credits.
  • A local filesystem path only works on the local stdio server; the hosted server refuses it, and there is no URL to hand it for a file on your own disk. Use request_screenshot_upload there instead.
  • An import that produced refs put the bytes in ShotOps storage, and the reply discloses what moved, why, how long it is kept and what retains it. A local path import moves nothing and discloses nothing.

When it refuses

One entry failed and the rest succeeded.
That is by design. Re-import just the failed entry; the refs you already got stay valid.
An entry names two sources at once.
Every entry names exactly one of url, file or path. The reply says which entry and what to drop.
A path was refused on the hosted server.
Hosted has no access to your filesystem. Either give a URL it can fetch, or mint a signed upload.

Where this fits

What the agent is told

The title and description the server publishes on tools/list — this is the copy a model chooses between, reproduced verbatim.

Import screenshots

How screenshots that exist only in THIS conversation get into ShotOps so they can be rendered: one call takes several — an attached PNG or JPEG, or a PNG/JPEG URL — and hands each back as a private, account-scoped `ref` the render tools accept, with the image bytes moving server-to-server so they never enter model context. Every entry of `screenshots` names EXACTLY ONE source: { "url": "https://…" } (this server fetches PNG or JPEG and converts JPEG to PNG — works on any client), { "file": … } (a ChatGPT attachment descriptor; in ChatGPT it arrives as the top-level `file` parameter instead), or (local stdio server only) { "path": "/abs/shot.png" }. Results come back one per entry in input order, and a failed entry reports its own error without cancelling the rest — re-import just that one. Then call render_strip with the preferred flat input { "screenshots": [{ "ref": "THE_REF" }] }; the same refs work in emit_bundle, and with their filenames in render_project. If the screenshots are only on the user's machine and this is the hosted server, there is no URL to give — use request_screenshot_upload instead. An import that produced refs puts the bytes in ShotOps storage and says so in a `disclosure` block: what moved, why, how long it is kept and the explicit action that retains it. A local { "path" } import moves nothing and discloses nothing.