> For the complete documentation index, see [llms.txt](https://help.smartico.ai/welcome/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.smartico.ai/welcome/technical-guides/mcp-server/mcp-how-to-manage-images.md).

# MCP - How to manage images

The Smartico Model Context Protocol (MCP) Server lets AI assistants, external applications, and automated scripts manage the media files in your Smartico account. Using MCP tools, you can search library assets, inspect file dimensions and metadata, update tags, upload new images, and delete unused media. Each uploaded file is stored in your media library and served from Smartico's CDN, giving it a persistent `file_url_cdn` URL that you can use in gamification features, communication templates, and on-site banners.

Connecting through an AI client (such as Claude Desktop) or calling the endpoint directly via standard HTTP JSON-RPC 2.0 requests uses the exact same permission model and validation rules. For full details on authentication and server setup, see [MCP Server](/welcome/technical-guides/mcp-server.md). For profile-based tool access restrictions, see [MCP Access Profiles](/welcome/technical-guides/mcp-server/mcp-access-profiles.md).

## Overview of MCP Image and Media Tools

Media files are represented by the `media` entity type and a dedicated upload operation. Rather than creating files directly with standard entity creation, media ingestion uses an operation that downloads, validates, and optimizes the asset for CDN delivery.

| Tool                              | Action             | Description                                                                                                                                            |
| --------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `entity_list`                     | Search / List      | Finds media files by file name, tag, uploader, or MIME type. Requires at least one narrowing search filter.                                            |
| `entity_get`                      | Retrieve           | Fetches detailed metadata for a specific media file by its numeric `file_id`.                                                                          |
| `exec_operation` (`upload_media`) | Upload             | Adds an image, video, audio, PDF, or JSON animation to the media library from an external HTTPS URL or Base64 payload. Returns the persistent CDN URL. |
| `entity_update`                   | Edit Tags / Delete | Replaces a file's assigned tags or soft-deletes the file from the media library (`is_deleted: true`).                                                  |
| `entity_describe`                 | Schema Discovery   | Returns field specifications, search filters, and usage guidelines for `entity_type: "media"`.                                                         |
| `read_resource`                   | Spec Reference     | Reads the full parameter specification for `upload_media` at `smartico://operation/upload-media`.                                                      |

{% hint style="info" %}
**Why `entity_create` is disabled for media:** Calling `entity_create` with `entity_type: "media"` returns an intentional error guiding callers to `exec_operation` with `upload_media`. Image uploads require content sniffing, file validation, security checks, and CDN ingestion, which are handled by the dedicated upload operation.
{% endhint %}

## Searching and Discovering Images

Because an operator's media library can contain thousands of assets, `entity_list` enforces guardrail filters to prevent unbounded listings. When querying `entity_type: "media"`, your request **must include at least one** of the following primary search filters:

* `file_name_original`: Search by file name (partial match, minimum 3 characters), or `@<file_id>` to locate a specific file by ID.
* `file_tag_names`: Search by tag name (exact match, such as `"Missions"`, `"Badges"`, `"Levels"`, `"Banners"`, `"Inbox"`, or `"MCP"`). Providing an array matches files containing any of the listed tags.
* `username`: Search by the back-office username of the person who uploaded the file (partial match).

### Narrowing and Sorting

* **MIME type filtering:** Pass `mimetype` to filter by category or specific format (e.g. `"image"`, `"image/png"`, `"image/jpeg"`, `"image/webp"`, `"image/gif"`, `"video/mp4"`, `"application/pdf"`, `"application/json"`). The `mimetype` filter must be combined with one of the primary filters above.
* **Sorting:** By default, results are sorted by `create_date` descending (newest uploads first). You can also sort by `id` or `file_size`.
* **Pagination:** Standard `limit` (default 20) and `offset` parameters are supported.

### Media Record Fields

Each returned media record provides the following fields:

| Field                | Type           | Description                                                                                             |
| -------------------- | -------------- | ------------------------------------------------------------------------------------------------------- |
| `file_id`            | integer        | Unique identifier of the file in the media library.                                                     |
| `file_name_original` | string         | Sanitized original filename stored in the library.                                                      |
| `file_url_cdn`       | string         | Public HTTPS address on the Smartico CDN to use in content.                                             |
| `mimetype`           | string         | Original MIME type detected from the uploaded file's binary content.                                    |
| `mimetype_final`     | string / null  | Final MIME type served by the CDN if converted (for example, `image/webp`), or `null` if kept original. |
| `file_size`          | integer        | Size of the stored file in bytes.                                                                       |
| `width`              | integer / null | Image width in pixels (`null` for non-images).                                                          |
| `height`             | integer / null | Image height in pixels (`null` for non-images).                                                         |
| `file_tag_names`     | array          | List of tags assigned to the file.                                                                      |
| `username`           | string / null  | Back-office username of the uploader.                                                                   |
| `create_date`        | string         | Upload timestamp (UTC).                                                                                 |
| `is_deleted`         | boolean        | Deletion status (`false` for active files). Deleted files are excluded from `entity_list`.              |

## Uploading Images with `upload_media`

To add a file to the media library, call `exec_operation` with `operation: "upload_media"`. The server downloads or decodes the content, detects its format by inspecting file headers (not just file extensions), uploads it to CDN storage, and assigns standard tags.

### Parameters

* **File Source (exactly one required):**
  * `file_url` (string): A public HTTPS URL where the file can be downloaded. Must use the standard HTTPS port (443), must not point to private or internal IP addresses, and follows at most 3 redirects.
  * `file_data` (string): The file content provided directly as Base64 text or a data URI (e.g. `data:image/png;base64,...`). Ideal for programmatic scripts or AI workflows that generate assets in memory.
* `file_name_original` (string, optional): Desired filename (e.g. `"gold-badge-icon.png"`). The system cleans the name to alphanumeric characters and dashes, and automatically enforces the extension matching the detected MIME type.
* `uploader_context` (string, optional, default `"none"`): Controls how the file is stored and whether format conversion is applied:
  * `"none"`: General media library asset. When account-level image optimization is active, images are automatically compressed and converted to WebP for faster delivery.
  * `"banners"`: Retains the original image format without converting to WebP.
  * `"mail_editor"`: Retains original PNG or JPEG format without WebP conversion, preventing rendering problems in email clients that lack WebP support.
  * `"avatars"`: Formatted for player avatars (capped at 50 KB, square resolution recommended).
  * `"rcs"`, `"faq"`: Optimized for RCS communication channels or Help Center articles.
* `file_tag_names` (array of strings, optional): Up to 10 custom tags (3–50 characters each). The server automatically tags every upload with `"MCP"`, which is merged with any custom tags you specify.
* `dry_run` (boolean, top-level argument, default `false`): When `true`, downloads or decodes the file and checks its dimensions and type without saving it or storing it on the CDN.
* **URL Download Restrictions:** When using `file_url`, the server downloads the asset directly. For security and stability, the target URL must use standard HTTPS (port 443), cannot contain embedded credentials (`user:password@`), must not resolve to private or internal IP addresses or Smartico internal hostnames, and follows at most 3 redirects. Additionally, HTTP compressed transfer encodings (`gzip`, `br`) are refused—the server requires direct binary delivery with `Accept-Encoding: identity`.

### Supported File Formats and Limits

* **Images:** PNG, JPEG, GIF, WebP (up to 512 KB), and AVIF (up to 5 MB). Player avatars are capped at 50 KB. SVG and HTML files are strictly refused for security reasons.
* **Videos:** MP4, WebM, MPEG (up to 5 MB).
* **Audio:** MP3, M4A (up to 1 MB).
* **Documents & Animations:** PDF and JSON (e.g. Lottie animations) up to 5 MB.

## Updating Tags and Deleting Images

Existing files can be modified using `entity_update` with `entity_type: "media"`:

* **Updating Tags:** Send `file_id` and `file_tag_names` with the complete replacement list of tags. Tags must be 3–50 characters. Tags that do not yet exist in your label are created automatically. Passing an empty array `[]` removes all tags from the file.
* **Deleting Files:** Send `file_id` and `is_deleted: true`. Deleting a file removes it from the media library and clears its tags. A deleted file cannot be restored or edited. Note that existing cached links in live messages will continue to resolve from CDN edge servers, but the asset is removed from the back-office library.
* **Safety Preview:** Pass `dry_run: true` to view a before-and-after diff of tag or deletion changes before committing them.
* **Tag Limit:** A file accepts a maximum of 10 tags. Updating tags replaces the entire tag set; to preserve the `"MCP"` tag on an asset after an update, you must include `"MCP"` in the `file_tag_names` array.
* **TOON Format for AI Agents:** When communicating with the MCP server in the default TOON format, update fields are structured under a single root `media:` block specifying `file_id` and the target properties (such as `file_tag_names` or `is_deleted`).

## Direct REST API Requests (cURL)

You can execute all image search, upload, and update actions using standard HTTP requests without an AI client. Send a `POST` request to your environment's MCP endpoint using JSON-RPC 2.0.

### Base Request Format

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '<JSON-RPC payload>'
```

Replace `<N>` with your environment number (for example, `aichat-api8.smartico.ai`), and `<your-token>` with your static MCP token generated under **MCP → Access tokens**.

### 1. Search Images by Tag and Type

Find all images tagged `"Missions"`:

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "entity_list",
      "arguments": {
        "entity_type": "media",
        "filters": {
          "file_tag_names": ["Missions"],
          "mimetype": "image"
        },
        "limit": 10
      }
    }
  }'
```

### 2. Search Images by Filename

Search for files containing `"tournament"` in the original filename:

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "entity_list",
      "arguments": {
        "entity_type": "media",
        "filters": {
          "file_name_original": "tournament"
        },
        "limit": 10
      }
    }
  }'
```

### 3. Retrieve a Specific Media Record

Fetch full metadata and dimensions for file ID `1042`:

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "entity_get",
      "arguments": {
        "entity_type": "media",
        "id": 1042
      }
    }
  }'
```

### 4. Upload an Image by URL

Upload a promotional banner from an external URL, setting the context to `"banners"` to preserve its original PNG format:

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 4,
    "method": "tools/call",
    "params": {
      "name": "exec_operation",
      "arguments": {
        "operation": "upload_media",
        "params": {
          "file_url": "https://assets.example.com/promotions/weekend-championship.png",
          "file_name_original": "weekend-championship.png",
          "uploader_context": "banners",
          "file_tag_names": ["Tournaments", "WeekendPromo"]
        },
        "dry_run": false
      }
    }
  }'
```

### 5. Upload an Image via Base64 Payload

Upload a small 1×1 test PNG using a Base64 data string:

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 5,
    "method": "tools/call",
    "params": {
      "name": "exec_operation",
      "arguments": {
        "operation": "upload_media",
        "params": {
          "file_data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
          "file_name_original": "custom-badge.png",
          "uploader_context": "none",
          "file_tag_names": ["Badges"]
        },
        "dry_run": false
      }
    }
  }'
```

### 6. Test Upload with Dry Run

Validate a file without saving it to storage or creating a library record:

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 6,
    "method": "tools/call",
    "params": {
      "name": "exec_operation",
      "arguments": {
        "operation": "upload_media",
        "params": {
          "file_url": "https://assets.example.com/icons/vip-star.png",
          "file_name_original": "vip-star.png"
        },
        "dry_run": true
      }
    }
  }'
```

### 7. Update Media Tags

Replace the tags on file `1042` with new categories:

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 7,
    "method": "tools/call",
    "params": {
      "name": "entity_update",
      "arguments": {
        "entity_type": "media",
        "payload": {
          "file_id": 1042,
          "file_tag_names": ["Missions", "VIP", "Autumn2026"]
        },
        "dry_run": false
      }
    }
  }'
```

### 8. Delete a Media File

Remove file `1042` from the media library:

```bash
curl -X POST https://aichat-api<N>.smartico.ai/mcp \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-mode: json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 8,
    "method": "tools/call",
    "params": {
      "name": "entity_update",
      "arguments": {
        "entity_type": "media",
        "payload": {
          "file_id": 1042,
          "is_deleted": true
        },
        "dry_run": false
      }
    }
  }'
```

## Using Uploaded Images Across Smartico Features

Once an image is uploaded and its `file_url_cdn` is returned, you can attach the URL to any platform entity using standard MCP entity tools or back-office editors:

* **Gamification Badges and Missions:** In the Back-Office editor, paste the `file_url_cdn` into the image field of the mission or badge (missions and badges are read-only through MCP).
* **Gamification Levels:** Pass the `file_url_cdn` as the icon for level tiers (Bronze, Silver, Gold).
* **Communication Templates:** Use the URL inside email templates, popup creatives, push notification rich images, or inbox message preview icons.
* **Banners & Placements:** Set the banner creative URL when managing banner entities.
* **Player Avatars:** Use `uploader_context: "avatars"` and attach the URL to an avatar entity.

## Frequently Asked Questions

**Can I generate images from text prompts (like "Create an image for missions named 'UEFA Champions'") directly in MCP?**\
The Smartico back-office UI includes an AI assistant helper button beside image upload fields that formats prompt suggestions (e.g., *"Create an image for 'missions' named '...' "*). However, the MCP server itself does not run an internal generative diffusion model. Instead, MCP serves as the asset management and ingestion pipeline: an external AI assistant (or script) generates the desired image using its own generative model, sends the generated image bytes to Smartico via `upload_media`, and attaches the resulting `file_url_cdn` to the target entity (such as a mission or badge).

**Why can't I create media files using `entity_create`?**\
Media assets require binary decoding, content type verification, format conversion, and CDN synchronization. Calling `entity_create` on `media` is explicitly blocked; always use `exec_operation` with `upload_media` instead.

**Why do some images appear blurry or with black borders in email clients?**\
By default (`uploader_context: "none"`), Smartico optimizes images by converting them to WebP to reduce bandwidth and speed up widget loading. However, certain email clients (such as older versions of Outlook) do not support WebP, resulting in pixelation or dark borders. When uploading images intended for email communications, always specify `uploader_context: "mail_editor"`. This tells the server to preserve the original PNG or JPEG format.

**What happens if I upload an image without specifying tags?**\
Every file uploaded through the MCP server automatically receives the system tag `"MCP"`. If you specify custom tags in `file_tag_names`, your tags are combined with `"MCP"`. This allows back-office team members to easily filter and review all assets introduced through automated tools.

**Can deleted images be recovered?**\
No. When an image is updated with `is_deleted: true`, its record in the media library is permanently marked as deleted and its associated tags are removed. The file cannot be restored or edited through the API. Cached images in active campaigns will continue to serve until their CDN cache expires, but the asset cannot be re-selected in the back office.

**Can I upload SVG files through MCP?**\
No. For security reasons, SVG, HTML, and scriptable vector files are rejected. The media uploader accepts raster images (PNG, JPEG, GIF, WebP, AVIF), videos (MP4, WebM, MPEG), audio (MP3, M4A), and documents/animations (PDF, JSON/Lottie).

**Can I upload multiple media files in a single request?**\
No. Each `upload_media` call accepts exactly one file via either `file_url` or `file_data`. To upload multiple assets (for example, a set of badge icons or level graphics), invoke `upload_media` separately for each file.

**Which tags should I assign so that uploaded images appear in specific Back-Office feature menus?**\
The Back-Office asset selector filters images using standard system tags. To make your uploaded images easily selectable in specific feature drawers, include standard tags in `file_tag_names`, such as `"Missions"`, `"Badges"`, `"Levels"`, `"Tournaments"`, `"Mini games"`, `"Store"`, `"Banners"`, or `"Avatars"`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.smartico.ai/welcome/technical-guides/mcp-server/mcp-how-to-manage-images.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
