@wavespeed/mcp 1.0.13 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,10 +35,11 @@ Built on the same design as the open-source [`@wavespeed/cli`](https://github.co
35
35
  | `get_model_schema` | A model's real input schema (required, properties, defaults) |
36
36
  | `run_model` | Submit + wait; rejects input keys the model doesn't accept; `@path` inputs upload automatically; returns output URLs |
37
37
  | `get_price` | Cost estimate with `unpriced_inputs` / `at_base_price` disclosure |
38
- | `get_balance` | Account credit balance |
38
+ | `get_balance` | Account credit balance, with the top-up link |
39
39
  | `list_predictions` | Run history (default last 24h); filter by model, status, time range |
40
40
  | `list_billings` | Itemized charges and refunds (needs a Billing-access key) |
41
41
  | `get_usage` | Spend, request counts and per-model breakdown (default last 7 days; needs a Billing-access key) |
42
+ | `delete_predictions` | Delete finished runs from the history (up to 100; needs `confirm: true`, cannot be undone from here) |
42
43
  | `upload_file` | Local file → hosted URL (24h content-hash dedupe) |
43
44
  | `get_prediction` | Status/outputs of any run by id; optional `wait_seconds` to wait for it |
44
45
 
package/dist/lib/api.js CHANGED
@@ -256,3 +256,7 @@ export async function waitForPrediction(id, opts = {}) {
256
256
  await new Promise((r) => setTimeout(r, interval));
257
257
  }
258
258
  }
259
+ // Deletes within the key's own organization; the response lists the ids actually deleted.
260
+ export async function deletePredictions(ids) {
261
+ return apiPost('/api/v3/predictions/delete', { ids }, { timeoutMs: GET_TIMEOUT_MS });
262
+ }
@@ -0,0 +1,34 @@
1
+ // delete_predictions: the checks and the report around POST /api/v3/predictions/delete.
2
+ // The API only touches the key's own organization and returns the ids it deleted.
3
+ export const MAX_DELETE_IDS = 100;
4
+ const ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
5
+ /** The ids to send: trimmed, unique, valid, and only once the user agreed (confirm). */
6
+ export function prepareDelete(ids, confirm) {
7
+ const unique = [];
8
+ for (const raw of ids) {
9
+ const id = raw.trim();
10
+ if (!ID_PATTERN.test(id))
11
+ throw new Error(`Invalid prediction id "${raw}".`);
12
+ if (!unique.includes(id))
13
+ unique.push(id);
14
+ }
15
+ if (unique.length === 0 || unique.length > MAX_DELETE_IDS) {
16
+ throw new Error(`Pass between 1 and ${MAX_DELETE_IDS} prediction ids.`);
17
+ }
18
+ if (!confirm) {
19
+ throw new Error(`Nothing was deleted. This removes ${unique.length} prediction(s) from the history and cannot be undone here: ask the user, then call again with confirm: true.`);
20
+ }
21
+ return unique;
22
+ }
23
+ export function summarizeDelete(requested, deletedIds) {
24
+ const deleted = deletedIds ?? [];
25
+ const notDeleted = requested.filter((id) => !deleted.includes(id));
26
+ return {
27
+ deleted,
28
+ deleted_count: deleted.length,
29
+ requested: requested.length,
30
+ ...(notDeleted.length > 0
31
+ ? { not_deleted: notDeleted, note: "These ids were not deleted: they are not in this account's history, are still running, or were already deleted." }
32
+ : {}),
33
+ };
34
+ }
package/dist/server.js CHANGED
@@ -15,8 +15,11 @@ import { createRequire } from 'node:module';
15
15
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
16
16
  import { z } from 'zod';
17
17
  import { Client } from 'wavespeed';
18
- import { fetchModels, fetchBalance, fetchHistory, fetchBillings, fetchUsageStats, PREDICTION_STATUSES, fetchPricing, submitPrediction, waitForPrediction, MCP_CLIENT_NAME, TERMINAL_FAILURES, } from './lib/api.js';
18
+ import { fetchModels, fetchBalance, fetchHistory, fetchBillings, fetchUsageStats, deletePredictions, PREDICTION_STATUSES, fetchPricing, submitPrediction, waitForPrediction, MCP_CLIENT_NAME, TERMINAL_FAILURES, } from './lib/api.js';
19
19
  import { getApiKey, getBaseUrl } from './lib/config.js';
20
+ import { MAX_DELETE_IDS, prepareDelete, summarizeDelete } from './lib/delete-predictions.js';
21
+ // Where to add credit; handed to the assistant next to the balance.
22
+ const TOP_UP_URL = 'https://wavespeed.ai/top-up';
20
23
  import { resolveLocalFiles } from './lib/local-files.js';
21
24
  import { uploadWithCache } from './lib/upload-cache.js';
22
25
  import { missingPriceVars, isFloorQuote } from './lib/pricing-vars.js';
@@ -240,8 +243,8 @@ export function createServer() {
240
243
  disclaimer: PRICE_DISCLAIMER,
241
244
  });
242
245
  });
243
- server.tool('get_balance', 'Show the WaveSpeed account credit balance.', {}, { readOnlyHint: true, openWorldHint: true }, async () => {
244
- return ok(await fetchBalance());
246
+ server.tool('get_balance', 'Show the WaveSpeed account credit balance, with the link to top up.', {}, { readOnlyHint: true, openWorldHint: true }, async () => {
247
+ return ok({ ...(await fetchBalance()), top_up_url: TOP_UP_URL });
245
248
  });
246
249
  server.tool('list_predictions', 'List past predictions (run history), newest window first. Defaults to the last 24 hours; pass since/until (ISO or YYYY-MM-DD) for other ranges. Use get_prediction with an id for one task in full.', {
247
250
  page: z.number().int().min(1).default(1),
@@ -288,6 +291,14 @@ export function createServer() {
288
291
  const start = toIso(since, 'since') ?? new Date(Date.parse(end) - 7 * 24 * 60 * 60 * 1000).toISOString();
289
292
  return ok(await fetchUsageStats(start, end, model));
290
293
  });
294
+ server.tool('delete_predictions', `Delete finished predictions from this account's run history, up to ${MAX_DELETE_IDS} at a time. They stop appearing in list_predictions and get_prediction, and this tool cannot bring them back. Runs that are still going are left alone, and only the key's own organization's records are deleted. Ask the user first, and pass confirm: true only after they agreed to delete these ids.`, {
295
+ ids: z.array(z.string()).min(1).max(MAX_DELETE_IDS).describe('Prediction ids to delete'),
296
+ confirm: z.boolean().describe('Must be true: the user has agreed to delete these predictions'),
297
+ }, { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false }, async ({ ids, confirm }) => {
298
+ const toDelete = prepareDelete(ids, confirm);
299
+ const res = await deletePredictions(toDelete);
300
+ return ok(summarizeDelete(toDelete, res.deleted_ids));
301
+ });
291
302
  server.tool('upload_file', 'Upload a local file to WaveSpeed and get its hosted URL (identical bytes reuse the same upload for 24h). Usually unnecessary — run_model handles "@./path" inputs itself.', { path: z.string().describe('Local file path') }, { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async ({ path: filePath }) => {
292
303
  return ok(await uploadFile(filePath));
293
304
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wavespeed/mcp",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "WaveSpeed MCP server — run any model on the live WaveSpeed catalog (image, video, audio, 3D) with schema introspection, local-file upload, and price quotes.",
5
5
  "type": "module",
6
6
  "bin": {