# SpicyAPI MCP (npm · @spicyapi/mcp)

Image, video and audio generation APIs with USD quotes and confirmation before paid requests.

- Trust score: 79/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- npm · `@spicyapi/mcp`: 79/100 (this document), [markdown](https://verifymcp.io/servers/spicyapi-ai-mcp/spicyapi-mcp.md), [page](https://verifymcp.io/servers/spicyapi-ai-mcp/spicyapi-mcp)

## Channel facts

- Registry: `npm`
- Package: `@spicyapi/mcp`
- Version: `0.6.2`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 83/100
  - No malware found by supply-chain analysis.
  - CVE check failed: a known high-severity CVE affects @modelcontextprotocol/node 2.0.0, a direct dependency. A fixed version is available.
  - No install/post-install scripts declared.
  - 0 of 10 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 100/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to spicyapi-ai/spicy-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 1 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 75/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 3982 tokens (~165/item across 24 items; 22 tools + 2 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 30/100
  - Stability observed for 9 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 83/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 39% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 2 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 24 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the SpicyAPI MCP server?

SpicyAPI MCP runs locally as an npm package, launched with npx -y @spicyapi/mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add spicyapi-ai-mcp -- npx -y @spicyapi/mcp
```

### Cursor

```json
{
  "mcpServers": {
    "spicyapi-ai-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@spicyapi/mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "spicyapi-ai-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@spicyapi/mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add spicyapi-ai-mcp -- npx -y @spicyapi/mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "spicyapi-ai-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@spicyapi/mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add spicyapi-ai-mcp --command npx --arg -y --arg @spicyapi/mcp
```

### Hermes

```yaml
mcp_servers:
  spicyapi-ai-mcp:
    command: "npx"
    args: ["-y", "@spicyapi/mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "spicyapi-ai-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "@spicyapi/mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add spicyapi-ai-mcp -t stdio -c npx -a -y @spicyapi/mcp
```

### Other

```json
{
  "mcpServers": {
    "spicyapi-ai-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@spicyapi/mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-04 (score 79, +16)

- [security improvement] Malware scan: unverified → pass

### 2026-11-03 (score 63, −12)

- [security regression] Malware scan: pass → unverified
- [functional regression] Schema quality: 146 → 165
- [functional improvement] Stability: unverified → 0.23
- [functional] Package version: 0.6.1 → 0.6.2

### 2026-10-29 (score 75, 0)

- [security regression] CVE-2026-118663 affects this package: high

### 2026-10-28 (score 75, +15)

- [security regression] GHSA-f897-62hf-6gxq affects this package: high
- [security improvement] Malware scan: unverified → pass

### 2026-10-27 (score 60)

First indexed and scored.

## MCP tools (22)

### `spicyapi_service_status` (~96 tokens)

Check SpicyAPI service status

Read public health and readiness endpoints for diagnostics or an explicit status request. Not a prerequisite for task creation. No API key is required. Report the `operational` field. On the public surface /readyz answers 404 by design — readiness exposes database and Redis state, so it is registered only on the admin process — and `operational` already accounts for that. Do not report a 404 there as an outage.

Output parameters:

- `result` (object)

### `spicyapi_docs_search` (~35 tokens)

Search SpicyAPI documentation

Search the bundled index of verified first-party documentation URLs.

Input parameters:

- `limit` (integer)
- `query` (string)

Output parameters:

- `result` (array)

### `spicyapi_models_list` (~235 tokens)

List callable SpicyAPI models

Discover enabled models and account-specific prices. Fetch only the selected model for its schema, or set includeSchema to reuse complete records without another model_get call. Returned input schemas are plain JSON Schema; display-only and rate-card annotations are removed. Some input values change the price; task_create obtains the exact request quote for confirmation. Use pricing entries for comparisons rather than calculating the accepted charge yourself. Models with task `realtime` or `realtime-transcription` take one bounded turn as a task from their input schema; live, continuous audio needs a server-side WebSocket to wss://api.spicyapi.ai/v1/realtime, which this server does not open. Embedding models (task `embedding`) and text-to-speech models are also served by OpenAI-compatible POST /v1/embeddings and POST /v1/audio/speech for applications that want vectors or audio bytes directly.

Input parameters:

- `includeExamples` (boolean)
- `includeSchema` (boolean)
- `modality` (string)
- `provider` (string)
- `search` (string)
- `task` (string)

Output parameters:

- `result` (object)

### `spicyapi_model_get` (~94 tokens)

Get one SpicyAPI model

Return one exact model, its live input schema, pricing, policy and availability. Reuse a complete record already obtained from models_list with includeSchema. The input schema is plain JSON Schema; display-only and rate-card annotations are removed. Some input values change the price; task_create obtains the exact request quote for confirmation. Use pricing entries for comparisons rather than calculating the accepted charge yourself.

Input parameters:

- `model` (string, required)

Output parameters:

- `result` (object)

### `spicyapi_balance_get` (~41 tokens)

Get SpicyAPI USD balance

Return available, held, and total balance as exact decimal USD strings when requested or diagnosing funds. Task creation already checks funds; this is not a prerequisite.

Output parameters:

- `result` (object)

### `spicyapi_usage_get` (~149 tokens)

Get current SpicyAPI key usage

Read task counts and settled actual USD spend for the current API key, grouped by creation day and model. Only from/to dates are accepted: UTC [from,to), at most 92 days; defaults to seven days ending tomorrow UTC. Money is returned as exact decimal strings; pending holds are excluded and late settlement can change prior-day spend. This is not account balance or remaining key budget, and is not a generation prerequisite. Use for requested usage reports; respect Retry-After on rate limits.

Input parameters:

- `from` (string): Inclusive UTC date, YYYY-MM-DD. Defaults to seven days before to.
- `to` (string): Exclusive UTC date, YYYY-MM-DD. Defaults to tomorrow UTC.

Output parameters:

- `result` (object)

### `spicyapi_tasks_list` (~148 tokens)

List current SpicyAPI key tasks

Discover current-key task history with metadata only, without fetching each result. Dates are UTC [from,to), default seven days, at most 92 days. Keep from/to fixed across pages and pass nextCursor unchanged. Limit defaults to 20, maximum 100. Cost is an exact USD string and is final only when settled. Use task_get only for selected results; use usage_get for settled spending including hidden tasks. This is not a polling endpoint or a prerequisite to generation.

Input parameters:

- `cursor` (string)
- `from` (string)
- `limit` (integer)
- `model` (string)
- `state` (string)
- `to` (string)

Output parameters:

- `result` (object)

### `spicyapi_task_get` (~269 tokens)

Get a SpicyAPI task

Read a task created by the current API key, including ready output.assets[].url links. Use those URLs directly without your API key; query again if assets are pending or URLs have expired. A verified complete v2 webhook already contains the result. Unknown and inaccessible IDs are both 404. Some models answer in words instead of a file: speech-to-text and other text results arrive in output.text with no assets, and a transcription may add output.transcript with word timings, timed segments (output.transcript.segments, with speaker labels when available) and the detected language. Embedding models return vectors in output.embeddings (inputTokens and data[].index/embedding); large results are summarized here, see output.embeddings.summary. Layer decomposition returns one image asset per layer; stack them by ascending output.assets[].layer.zIndex. Other asset roles: image-to-3d and text-to-3d return one `mesh` asset (a binary glTF .glb, mime model/gltf-binary); vector endpoints return `image` assets with mime image/svg+xml; video translation can add a `subtitle` asset (.srt); video extension that joins the source clip returns the joined `video` first and the new part as `segment`.

Input parameters:

- `taskId` (string, required)

Output parameters:

- `result` (object)

### `spicyapi_task_wait` (~328 tokens)

Wait briefly for a SpicyAPI task

Wait for a task for up to 300 seconds and read ready output.assets[].url directly without a download-ticket call. By default, polling backs off from about 2 to at most 10 seconds; an explicit intervalSeconds stays fixed. Prefer signed webhooks for production; a complete verified v2 callback needs no extra task_get. A local wait timeout does not cancel the task. Some models answer in words instead of a file: speech-to-text and other text results arrive in output.text with no assets, and a transcription may add output.transcript with word timings, timed segments (output.transcript.segments, with speaker labels when available) and the detected language. Embedding models return vectors in output.embeddings (inputTokens and data[].index/embedding); large results are summarized here, see output.embeddings.summary. Layer decomposition returns one image asset per layer; stack them by ascending output.assets[].layer.zIndex. Other asset roles: image-to-3d and text-to-3d return one `mesh` asset (a binary glTF .glb, mime model/gltf-binary); vector endpoints return `image` assets with mime image/svg+xml; video translation can add a `subtitle` asset (.srt); video extension that joins the source clip returns the joined `video` first and the new part as `segment`.

Input parameters:

- `intervalSeconds` (integer): Fixed polling interval in seconds. Omit to use adaptive SDK backoff from about 2 to at most 10 seconds.
- `taskId` (string, required)
- `timeoutSeconds` (integer)

Output parameters:

- `result` (object)

### `spicyapi_upload_file` (~185 tokens)

Upload a local file to SpicyAPI

Read a file from this computer, upload it, and return the spicy:// URI to put in a model input field. Use this whenever the user refers to a file on their machine. Images (JPEG, PNG, WebP, GIF) up to 10 MiB; MP4/WebM video and MP3/WAV audio up to 90 MiB; reference documents (PDF, Word, Excel, PowerPoint, Keynote, Pages, Numbers, TXT, Markdown) up to 90 MiB for fields such as reference_file_url. Public HTTPS media URLs need no upload at all — pass them straight to the model input when its schema accepts a URL.

Input parameters:

- `contentType` (string): Only when the file extension is missing or wrong; otherwise inferred.
- `path` (string, required): Absolute path to the file on this computer, as the user gave it.

Output parameters:

- `result` (object)

### `spicyapi_download_url_create` (~82 tokens)

Create a SpicyAPI output download URL

Create a short-lived signed URL for an output owned by the current task and API key, for legacy integrations or explicit link renewal. Prefer existing ready output.assets[].url from task_get, task_wait, or a verified v2 webhook; no ticket call is needed for those links.

Input parameters:

- `key` (string)
- `taskId` (string, required)

Output parameters:

- `result` (object)

### `spicyapi_task_quote` (~77 tokens)

Quote an exact SpicyAPI request

Compare an exact request price without creating a task or reserving funds. Returns a five-minute USD estimate and maximum charge. task_create already obtains its own quote and confirmation; do not call this tool as a routine prerequisite.

Input parameters:

- `callBackUrl` (string)
- `input` (object, required)
- `model` (string, required)

Output parameters:

- `result` (object)

### `spicyapi_task_create` (~306 tokens)

Create a billable SpicyAPI task

Obtain the exact request quote, show its USD estimate and maximum charge for user confirmation, then reserve funds and create an asynchronous task. Do not call task_quote first unless independently comparing prices. The confirmation needs an MCP client that supports form elicitation; if the client does not, the call fails after the free quote and no task is created or charged. Models with task `realtime` or `realtime-transcription` take one bounded turn as a task from their input schema; live, continuous audio needs a server-side WebSocket to wss://api.spicyapi.ai/v1/realtime, which this server does not open. Embedding models (task `embedding`) and text-to-speech models are also served by OpenAI-compatible POST /v1/embeddings and POST /v1/audio/speech for applications that want vectors or audio bytes directly.

Input parameters:

- `callBackUrl` (string)
- `idempotencyKey` (string)
- `input` (object, required)
- `model` (string, required)
- `retentionSeconds` (integer): How long SpicyAPI keeps this task's generated media, result payload, prompt and other input text, in seconds. Only ever shortens: the account settings and platform maximum still apply, so this cannot…

Output parameters:

- `result` (object)

### `spicyapi_task_retry` (~45 tokens)

Retry a billable SpicyAPI task

Create a new task from a failed or expired source. Requires a user confirmation round.

Input parameters:

- `idempotencyKey` (string)
- `taskId` (string, required)

Output parameters:

- `result` (object)

### `spicyapi_task_purge` (~207 tokens)

Destroy a SpicyAPI task's stored content

Permanently destroy one terminal task's stored content: generated media, result payload, prompt, and input text. This destroys content, not the record of what it cost — the ledger entry, charged amount, model, state, timestamps and request ID all stay queryable afterwards, so this never hides or reverses a charge and never refunds anything. It cannot be undone and there is no per-output granularity: the unit is one whole task. Download any result the user still wants before calling this. Only tasks in a terminal state are accepted. An accepted task cannot be canceled and there is no cancellation API, so for a queued or running task wait until it finishes (task_wait), then purge it. Repeating the call on an already destroyed task succeeds and changes nothing. Requires a user confirmation round.

Input parameters:

- `taskId` (string, required): The exact task whose content should be destroyed. Only call this for a task the user named; never sweep task history on your own initiative.

Output parameters:

- `result` (object)

### `spicyapi_assets_list` (~343 tokens)

List saved SpicyAPI assets

List files in the asset library this key reaches — the personal library for a personal key, the team's shared library for a team key — newest first unless sort says otherwise, one page at a time; pass nextCursor back as cursor with the same filters and sort to continue (a cursor from another sort is rejected with 400). Narrow it with favorite, collectionId (a folder; folders are created on the web, and an id outside this library is a 404), entityId (the images of one character) and query. Each item's uri (spicy://a/<id>) goes straight into any media field of a model input — no upload or download step. previewUrl is a private preview signed for at most 20 minutes; use it to show the file, never store it. A change the key's team role does not allow gets 403 with reason asset_permission_denied; a key that cannot reach the library gets 403 with asset_workspace_forbidden.

Input parameters:

- `collectionId` (string): Only the assets in this folder (a collection of the same library).
- `cursor` (string)
- `entityId` (string): Only the images of this character, from spicyapi_characters_list.
- `favorite` (boolean): true lists only favorites, false only assets that are not favorites.
- `kind` (string)
- `limit` (integer)
- `query` (string): Case-insensitive part of the asset name.
- `sort` (string): recent (default, newest first), oldest, name (A to Z) or size (largest first).
- `source` (array): Only assets saved from these sources.

Output parameters:

- `result` (object)

### `spicyapi_asset_save` (~369 tokens)

Save a file to the SpicyAPI asset library

Keep a file in the asset library this key reaches (personal, or the team's shared library for a team key) until it is deleted, and return its spicy://a/<id> uri for later model inputs made with keys of the same workspace. Give exactly one source: taskId (an output of one of the user's own successful tasks, or of the team's with a team key; index or key picks which, the first output by default), path (an absolute path to a file on this computer, uploaded first), url (a public http or https file), or fileId (a committed spicy://f/ upload). Saving the same task output, upload or URL again returns the existing asset. Storage unlocks with lifetime top-ups; a refusal carries a reason (asset_library_locked, asset_library_full, asset_file_too_large, asset_daily_limit, asset_storage_full) — call spicyapi_assets_usage_get to explain the plan rather than retrying.

Input parameters:

- `contentType` (string): With path: only when the file extension is missing or wrong.
- `fileId` (string): A committed upload: fil_… or spicy://f/…
- `idempotencyKey` (string): Reuse the key from an uncertain earlier attempt to replay that save. Not used with path, which uploads again on every call.
- `index` (integer): With taskId: zero-based position in output.assets.
- `key` (string): With taskId: the output key, instead of index.
- `name` (string): Up to 80 characters; a path defaults to its file name.
- `path` (string): Absolute path to a file on this computer, as the user gave it.
- `taskId` (string)
- `url` (string)

Output parameters:

- `result` (object)

### `spicyapi_asset_rename` (~74 tokens)

Rename a saved SpicyAPI asset

Change an asset's name. Its spicy://a/<id> uri stays the same, so model inputs that already use it keep working.

Input parameters:

- `assetId` (string, required): The asset id (ast_…) or its spicy://a/<id> reference; both are accepted.
- `name` (string, required)

Output parameters:

- `result` (object)

### `spicyapi_asset_delete` (~116 tokens)

Delete a saved SpicyAPI asset

Permanently delete one asset from the library this key reaches. Its spicy://a/<id> uri stops working in new requests at once and the stored file is removed; there is no undo. In a team library, developers can delete only what they saved. Deleting does not give back today's allowance of new assets. Only delete an asset the user named. Requires a user confirmation round.

Input parameters:

- `assetId` (string, required): The asset id (ast_…) or its spicy://a/<id> reference; both are accepted.

Output parameters:

- `result` (object)

### `spicyapi_assets_usage_get` (~117 tokens)

Get SpicyAPI asset library plan and usage

Return which library the key reaches (scope), the storage plan, what is stored against its limits, how many assets were saved today against the daily limit, and the next plan with how much more to top up. Usage covers the owner's whole allowance, shared by their personal and team libraries; the top-up amounts are absent when scope.canTopUp is false. Plans unlock with lifetime top-ups and never go down; byte values use binary units (500 MB = 524288000 bytes). Use it to explain a refused save.

Output parameters:

- `result` (object)

### `spicyapi_characters_list` (~204 tokens)

List SpicyAPI characters

List the characters in the asset library this key reaches: named sets of images, each image an asset with its own uri. Newest first, one page at a time; pass nextCursor back as cursor to continue. Pass assetId to find the characters that contain one asset. To use a character, put the uri (spicy://a/<id>) of its images, in the order given, into the reference image field of the model's input (spicyapi_model_get shows which field), and refer to them in the prompt the way that model's page describes. Characters are created and edited on the web; these tools only read them. Older spicy://p/<id> persona references still resolve to the same images, in the personal library only.

Input parameters:

- `assetId` (string): Only the characters that contain this asset (ast_… or spicy://a/<id>).
- `cursor` (string)
- `limit` (integer)

Output parameters:

- `result` (object)

### `spicyapi_character_get` (~171 tokens)

Get a SpicyAPI character

Read one character with its images in order, each with its uri and a fresh private previewUrl (signed for at most 20 minutes; never store it). An unknown character and one outside this key's library both return 404. To use a character, put the uri (spicy://a/<id>) of its images, in the order given, into the reference image field of the model's input (spicyapi_model_get shows which field), and refer to them in the prompt the way that model's page describes. Characters are created and edited on the web; these tools only read them. Older spicy://p/<id> persona references still resolve to the same images, in the personal library only.

Input parameters:

- `characterId` (string, required): The character id from spicyapi_characters_list.

Output parameters:

- `result` (object)

## Diagnostics

Captured diagnostic sections: Provenance, Vulnerabilities, Dependencies. The full working is on the page: https://verifymcp.io/servers/spicyapi-ai-mcp/spicyapi-mcp#diagnostics

## Score history

- 2026-11-05: 79
- 2026-11-04: 79
- 2026-11-03: 63
- 2026-11-02: 75
- 2026-11-01: 75
- 2026-10-31: 75
- 2026-10-30: 75
- 2026-10-29: 75
- 2026-10-28: 75
- 2026-10-27: 60

## Common questions

### What is the SpicyAPI MCP server?

SpicyAPI MCP is listed in the public MCP registry as io.github.spicyapi-ai/mcp. Image, video and audio generation APIs with USD quotes and confirmation before paid requests. This page covers its npm package (@spicyapi/mcp).

### Is the SpicyAPI MCP server safe to use?

SpicyAPI MCP scores 79 out of 100 on VerifyMCP. We recorded 6 known advisories against it as of 5 November 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the SpicyAPI MCP server expose?

SpicyAPI MCP exposes 22 tools: spicyapi_service_status, spicyapi_docs_search, spicyapi_models_list, spicyapi_model_get, spicyapi_balance_get, and 17 more. Their descriptions and schemas cost roughly 3,691 tokens of context every time the server is loaded.

### Is the SpicyAPI MCP server still maintained?

SpicyAPI MCP is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the SpicyAPI MCP server under?

SpicyAPI MCP declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/@spicyapi/mcp
- Socket report: https://socket.dev/npm/package/@spicyapi/mcp
- Repository: https://github.com/spicyapi-ai/spicy-mcp
- Website: https://spicyapi.ai/
- Changelog RSS feed: https://verifymcp.io/servers/spicyapi-ai-mcp/spicyapi-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/spicyapi-ai-mcp/spicyapi-mcp.json
- HTML version of this page: https://verifymcp.io/servers/spicyapi-ai-mcp/spicyapi-mcp
