@wavespeed/mcp 1.0.10 → 1.0.12

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
@@ -39,10 +39,34 @@ Built on the same design as the open-source [`@wavespeed/cli`](https://github.co
39
39
  | `upload_file` | Local file → hosted URL (24h content-hash dedupe) |
40
40
  | `get_prediction` | Status/outputs of any run by id; optional `wait_seconds` to wait for it |
41
41
 
42
- Some generations take minutes to hours. `run_model` waits up to `wait_seconds` (default 50, max 1800) and then returns `done: false` with the prediction id — the task keeps running server-side, and `get_prediction` picks it up. While waiting, both tools send MCP progress notifications that carry the prediction id.
42
+ Some generations take minutes to hours. `run_model` submits the run and returns the prediction id right away (`done: false`); the assistant then calls `get_prediction` with that id and `wait_seconds` (max 1800) until `done` is `true`. The task keeps running server-side, so a dropped connection loses nothing. Pass `wait_seconds` to `run_model` to wait for a quick model in the same call. While waiting, both tools send MCP progress notifications that carry the prediction id.
43
43
 
44
44
  ## Setup
45
45
 
46
+ ### Remote (nothing to install)
47
+
48
+ The same server is hosted at:
49
+
50
+ ```text
51
+ https://api.wavespeed.ai/mcp
52
+ ```
53
+
54
+ - **Claude on the web / ChatGPT:** add a custom connector with that address and approve the connection on the WaveSpeed page that opens. Approving creates a dedicated API key (named `MCP · <app>`) that you can delete on the [API Keys](https://wavespeed.ai/accesskey) page to disconnect.
55
+ - **Claude Code:** `claude mcp add --transport http wavespeed https://api.wavespeed.ai/mcp`
56
+ - **Cursor:**
57
+ <a href="https://cursor.com/install-mcp?name=wavespeed&config=eyJ1cmwiOiJodHRwczovL2FwaS53YXZlc3BlZWQuYWkvbWNwIn0%3D">
58
+ <picture>
59
+ <source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/deeplink/mcp-install-light.svg">
60
+ <img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Add the hosted wavespeed MCP server to Cursor" height="32"/>
61
+ </picture>
62
+ </a>
63
+ - **VS Code:** `code --add-mcp '{"name":"wavespeed","type":"http","url":"https://api.wavespeed.ai/mcp"}'`
64
+ - **Any other client that sends request headers:** point it at the URL with `Authorization: Bearer <your API key>`.
65
+
66
+ The hosted server has the same tools, with one difference for files: it cannot read files on your computer, so pass public URLs, use `create_upload` from a tool that can send HTTP requests (it returns a temporary upload address and the `download_url` to use as an input), or, in ChatGPT, attach the file to the chat (the `upload_attachment` tool, which only ChatGPT can fill, imports it and returns a `download_url`). Full guide: [wavespeed.ai/docs/mcp](https://wavespeed.ai/docs/mcp).
67
+
68
+ ### Local (npx)
69
+
46
70
  Auth resolves from `WAVESPEED_API_KEY`, or from the CLI's stored login (`wavespeed login`) — one login covers both tools. Keys: [wavespeed.ai/accesskey](https://wavespeed.ai/accesskey).
47
71
 
48
72
  **Claude Code**
package/dist/server.js CHANGED
@@ -43,13 +43,14 @@ async function uploadFile(filePath) {
43
43
  const client = new Client(apiKey, { baseUrl: getBaseUrl(), clientName: MCP_CLIENT_NAME });
44
44
  return uploadWithCache(filePath, (p) => client.upload(p));
45
45
  }
46
- // Default wait for run_model. Many MCP clients abort a tool call after 60s,
47
- // and an aborted call never delivers the prediction id — so return before
48
- // that with the id in hand. Longer waits are opt-in via wait_seconds.
49
- const DEFAULT_WAIT_SECONDS = 50;
46
+ // run_model submits and returns the prediction id right away (same as the
47
+ // hosted server); the assistant then waits with get_prediction. Many MCP
48
+ // clients abort a tool call after 60s and an aborted call never delivers the
49
+ // id, so a long wait is opt-in via wait_seconds.
50
+ const DEFAULT_WAIT_SECONDS = 0;
50
51
  const POLL_INTERVAL_MS = 2000;
51
- const STILL_RUNNING_HINT = 'Still running on the server — generations can take minutes to hours. ' +
52
- 'Call get_prediction with this id (optionally with wait_seconds) to check again.';
52
+ const STILL_RUNNING_HINT = 'The run was submitted and is processing on the server. Call get_prediction with this id and wait_seconds ' +
53
+ 'until done=true; it returns the output URLs. Do not submit the same run again: a new run is billed again.';
53
54
  // Emits notifications/progress while polling when the client asked for it.
54
55
  // Each one carries the prediction id, and clients that reset their timeout
55
56
  // on progress keep a long wait alive.
@@ -154,7 +155,7 @@ export function createServer() {
154
155
  property_order: schema?.['x-order-properties'] ?? [],
155
156
  });
156
157
  });
157
- server.tool('run_model', 'Run any WaveSpeed model. input keys come from get_model_schema; unknown keys are rejected before submission. Local files: pass "@./path" string values — they are uploaded and replaced with hosted URLs (bare paths are NOT uploaded). Returns output URLs when done=true. Some generations take minutes to hours: if the wait ends first, the result has done=false and the prediction id — the task keeps running, so check it with get_prediction.', {
158
+ server.tool('run_model', 'Run any WaveSpeed model. input keys come from get_model_schema; unknown keys are rejected before submission. Local files: pass "@./path" string values — they are uploaded and replaced with hosted URLs (bare paths are NOT uploaded). Returns the prediction id right away (done=false); call get_prediction with that id and wait_seconds until done=true to get the output URLs. The task keeps running on the server. Pass wait_seconds here to wait for a quick model in the same call.', {
158
159
  model: z.string().describe('Model ID from list_models'),
159
160
  input: z
160
161
  .record(z.unknown())
@@ -165,7 +166,7 @@ export function createServer() {
165
166
  .min(0)
166
167
  .max(1800)
167
168
  .default(DEFAULT_WAIT_SECONDS)
168
- .describe(`Max seconds to wait before returning the still-running prediction id (default ${DEFAULT_WAIT_SECONDS}); 0 = submit only`),
169
+ .describe(`Max seconds to wait for the result in this call (default ${DEFAULT_WAIT_SECONDS}: return the prediction id right away)`),
169
170
  }, { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, async ({ model, input, wait_seconds }, extra) => {
170
171
  const resolved = await resolveLocalFiles(input, {
171
172
  upload: async (p) => (await uploadFile(p)).url,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wavespeed/mcp",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
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": {