# create_article_image_upload (/docs/build/mcp-reference/create_article_image_upload)

{/* GENERATED by scripts/generate-mcp-reference.mjs from the MCP server tools/list. Do not edit. */}

| Group | Access | MCP name |
| --- | --- | --- |
| Articles | Writes data | `create_article_image_upload` |

## Description [#description]

The description the MCP server sends to the model, word for word. Its rules apply to every call.

> Get one-time upload URLs on writestack.io for an article image that has no public URL, such as a local file, an attachment you can read, or a private Google Drive file. Use it only when you can send the file's bytes yourself with an HTTP request (for example curl in a shell or code sandbox); if you cannot, ask the user for a public image URL instead. Pass the articleId, the file name, its exact contentType, and its exact size in bytes (max 10 MB). Within 15 minutes, send each entry in parts as an HTTP PUT of the raw bytes for that range (offset, sizeBytes) with the Content-Type header set to that contentType. A file up to 4 MB has one part: curl -X PUT -H 'Content-Type: &lt;contentType&gt;' --data-binary @&lt;file&gt; '&lt;uploadUrl&gt;'. A bigger file has 2 or 3 parts of 4 MB (4194304 bytes, the last one shorter); send them IN ORDER and wait for each 2xx, e.g. dd if=&lt;file&gt; bs=4194304 skip=&lt;part&gt; count=1 2&gt;/dev/null | curl -X PUT -H 'Content-Type: &lt;contentType&gt;' --data-binary @- '&lt;part url&gt;'. Do not use multipart/form-data and do not base64-encode the body. An error response says what did not match (type, size, order, or an expired link); fix it or call this tool again. After the last part succeeds, pass the returned imageUrl to update_article (imageUrl array to append it, or !\[alt](imageUrl) in bodyMarkdown to place it) or to create_article. Uploading alone does not add the image to the article. An imageUrl whose upload never finished is skipped.

## Arguments [#arguments]

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| `articleId` | `string` | Yes | The article the image is for. |
| `contentType` | `string` | Yes | Exact MIME type of the file. Send the same value as the Content-Type header on the PUT. One of: `"image/png"`, `"image/jpeg"`, `"image/gif"`, `"image/webp"`, `"image/avif"`, `"image/heic"`. |
| `fileName` | `string` | Yes | Original file name, e.g. cover.png. Used for the extension. Min length 1. Max length 200. |
| `sizeBytes` | `integer` | Yes | Exact file size in bytes (for example from `wc -c &lt; file` or `stat`). The upload must be exactly this size. Max 10 MB. Files over 4 MB are sent in parts. Max 10485760. |

## Example call [#example-call]

The smallest valid request: required arguments only, with placeholder values.

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "create_article_image_upload",
    "arguments": {
      "articleId": "…",
      "fileName": "…",
      "contentType": "image/png",
      "sizeBytes": 1
    }
  }
}
```

## Result [#result]

The result has `structuredContent` that matches this schema. The same data is also in `content` as JSON text.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `articleId` | `string` | Yes |  |
| `expiresAt` | `string` | Yes |  |
| `headers` | `object` | Yes |  |
| `headers.Content-Type` | `string` | Yes |  |
| `imageUrl` | `string` | Yes |  |
| `maxBytes` | `number` | Yes |  |
| `message` | `string` | Yes |  |
| `method` | `string` | Yes |  |
| `parts` | `object[]` | Yes |  |
| `parts[].offset` | `number` | Yes |  |
| `parts[].part` | `number` | Yes |  |
| `parts[].sizeBytes` | `number` | Yes |  |
| `parts[].url` | `string` | Yes |  |
| `uploadUrl` | `string` | Yes |  |

## Annotations [#annotations]

| Hint | Value |
| --- | --- |
| `readOnlyHint` | `false` |
| `destructiveHint` | `false` |
| `openWorldHint` | `false` |

The full input and output JSON Schemas for every tool are in [/mcp-tools.json](/mcp-tools.json).
