@fotor-ai/dsh-fotor-plugin 0.6.1 → 0.8.0

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.
Files changed (29) hide show
  1. package/INSTALL.md +7 -1
  2. package/README.md +6 -4
  3. package/configuration.example.yml +3 -3
  4. package/package.json +2 -2
  5. package/runtime/config.mjs +3 -2
  6. package/skills/fotor-audio/SKILL.md +27 -0
  7. package/skills/fotor-audio/references/authentication.md +68 -0
  8. package/skills/fotor-audio/references/credits.md +11 -0
  9. package/skills/fotor-audio/references/mcp-integration.md +140 -0
  10. package/skills/fotor-audio/references/media-upload.md +34 -0
  11. package/skills/fotor-connect/SKILL.md +2 -2
  12. package/skills/fotor-connect/references/credits.md +5 -30
  13. package/skills/fotor-connect/references/mcp-integration.md +20 -14
  14. package/skills/fotor-connect/references/media-upload.md +2 -2
  15. package/skills/fotor-credits/SKILL.md +3 -7
  16. package/skills/fotor-credits/references/credits.md +5 -30
  17. package/skills/fotor-credits/references/mcp-integration.md +20 -14
  18. package/skills/fotor-credits/references/media-upload.md +2 -2
  19. package/skills/fotor-image/references/credits.md +5 -30
  20. package/skills/fotor-image/references/mcp-integration.md +20 -14
  21. package/skills/fotor-image/references/media-upload.md +2 -2
  22. package/skills/fotor-upload/SKILL.md +2 -2
  23. package/skills/fotor-upload/references/credits.md +5 -30
  24. package/skills/fotor-upload/references/mcp-integration.md +20 -14
  25. package/skills/fotor-upload/references/media-upload.md +2 -2
  26. package/skills/fotor-video/SKILL.md +1 -1
  27. package/skills/fotor-video/references/credits.md +5 -30
  28. package/skills/fotor-video/references/mcp-integration.md +20 -14
  29. package/skills/fotor-video/references/media-upload.md +2 -2
package/INSTALL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Install and use Fotor with DeepSeek Harness
2
2
 
3
- DeepSeek Harness is abbreviated as `dsh` in commands and native identifiers. This guide describes automatic configuration in Fotor 0.6.1. Version 0.6.0 uses its documented manual configuration. Read the package README's version and channel, and choose a source that actually contains the target version. A candidate snapshot does not publish the npm package or change either default branch.
3
+ DeepSeek Harness is abbreviated as `dsh` in commands and native identifiers. This guide describes automatic configuration introduced in Fotor 0.6.1. Version 0.6.0 uses its documented manual configuration. Read the package README's version and channel, and choose a source that actually contains the target version. A candidate snapshot does not publish the npm package or change either default branch.
4
4
 
5
5
  ## 1. Check prerequisites
6
6
 
@@ -53,6 +53,12 @@ The adapter creates complete native `command`, `args`, `env` and `cwd` values in
53
53
 
54
54
  Optional MCP settings include `endpoint` (production Fotor by default; a loopback service is for isolated acceptance), `callbackPort`, and existing native stdio fields. A supplied `args` array is complete, not an append. Explicit `env.MCP_REMOTE_CONFIG_DIR` is preserved. The [full legacy configuration example](configuration.example.yml) remains available for advanced overrides; it is never auto-applied. Overrides replace the complete `config` object, not a deep merge.
55
55
 
56
+ ### Tool call timeouts
57
+
58
+ The native `fotor-mcp` component defaults to `toolCallTimeoutMs: 300000` (a total deadline in milliseconds). The generated bridge arguments use 300 seconds for response headers and body inactivity; the connection timeout stays 20 seconds. Startup recovery and the ten-minute authorization wait are separate limits.
59
+
60
+ To change the host deadline, set `toolCallTimeoutMs` in the component's native configuration. A saved complete `args` override retains its own bridge limits. Inspect both layers if a call ends early; edit or remove only the intended overrides through the same profile. No credential change is needed. A response near the upstream deadline can still be lost: keep any known task ID and never automatically repeat a submission.
61
+
56
62
  ## 5. Verify skills and existing overrides
57
63
 
58
64
  For ordinary use, verify the native skill menu/provider discovers the actual Fotor skills and their own `references` directories. A green component indicator without discovered entries is insufficient. Read known references through native `read`; the Shell sandbox may hide an otherwise readable host path.
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <p align="center"><img src="assets/logo.svg" width="72" alt="Fotor logo" /></p>
6
6
 
7
7
  <p align="center">
8
- <img src="https://img.shields.io/static/v1?label=version&amp;message=0.6.1&amp;color=087f8c&amp;style=flat-square" alt="Version" />
8
+ <img src="https://img.shields.io/static/v1?label=version&amp;message=0.8.0&amp;color=087f8c&amp;style=flat-square" alt="Version" />
9
9
  <img src="https://img.shields.io/static/v1?label=channel&amp;message=production&amp;color=238636&amp;style=flat-square" alt="Release channel" />
10
10
  <a href="LICENSE"><img src="https://img.shields.io/static/v1?label=license&amp;message=Apache-2.0&amp;color=57606a&amp;style=flat-square" alt="Apache-2.0 license" /></a>
11
11
  </p>
@@ -13,12 +13,12 @@
13
13
  <a href="#dsh"><img src="https://img.shields.io/static/v1?label=agent&amp;message=DeepSeek+Harness&amp;color=24292f&amp;style=flat-square" alt="DeepSeek Harness" /></a>
14
14
  </p>
15
15
 
16
- Use Fotor's shared skills with DeepSeek Harness Web and an automatically installed MCP bridge dependency.
16
+ Create images, video and audio with Fotor through DeepSeek Harness Web and an automatically installed MCP bridge dependency.
17
17
 
18
18
  | Field | Value |
19
19
  | --- | --- |
20
20
  | Bundle | `@fotor-ai/dsh-fotor-plugin` |
21
- | Version | `0.6.1` |
21
+ | Version | `0.8.0` |
22
22
  | Release channel | `production` |
23
23
  | Service environment | `production` |
24
24
  | MCP endpoint | `https://mcp.fotor.com/mcp` |
@@ -128,7 +128,7 @@ Uninstall retains external credentials but does not revoke server consent. Same-
128
128
 
129
129
  ## Workflows
130
130
 
131
- Start with [connection and model discovery](skills/fotor-connect/references/mcp-integration.md#runtime-workflow), then select the skill matching the request. Follow [media preparation](skills/fotor-connect/references/media-upload.md) for local references and [credits](skills/fotor-connect/references/credits.md) for balance/pricing requests. These instructions do not establish host acceptance of every media operation.
131
+ Start with [connection and model discovery](skills/fotor-connect/references/mcp-integration.md#runtime-workflow), then select the skill matching the request. Follow [media preparation](skills/fotor-connect/references/media-upload.md) for local references and [credits](skills/fotor-connect/references/credits.md) to query your own Fotor credit balance. These instructions do not establish host acceptance of every media operation.
132
132
 
133
133
  ## Bundle contents
134
134
 
@@ -148,4 +148,6 @@ Start with [connection and model discovery](skills/fotor-connect/references/mcp-
148
148
 
149
149
  ## Skill-local references
150
150
 
151
+ Audio workflows cover soundtrack composition, new tracks, song editing, speech, podcasts and vocal separation. Consult the installed audio skill when available. The host deadline and generated bridge header/body timeouts default to 300 seconds. See [tool call timeouts](INSTALL.md#tool-call-timeouts) for scopes and overrides. A deadline is not confirmation that a task failed; preserve any known ID without automatic resubmission.
152
+
151
153
  Every packaged skill carries four generated documents in its own `references/` directory, including this platform's authentication guide. Read them as needed; complete runtime documentation does not install or configure MCP.
@@ -36,10 +36,10 @@
36
36
  - --connect-timeout
37
37
  - '20'
38
38
  - --headers-timeout
39
- - '20'
39
+ - '300'
40
40
  - --body-timeout
41
- - '20'
41
+ - '300'
42
42
  env:
43
43
  MCP_REMOTE_CONFIG_DIR: /absolute/path/to/dsh-home/mcp-auth/fotor
44
44
  cwd: /absolute/path/to/workspace
45
- toolCallTimeoutMs: 25000
45
+ toolCallTimeoutMs: 300000
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fotor-ai/dsh-fotor-plugin",
3
- "version": "0.6.1",
4
- "description": "Connect to Fotor's production MCP service.",
3
+ "version": "0.8.0",
4
+ "description": "Connect to the Fotor MCP service to create images, video and audio.",
5
5
  "author": {
6
6
  "name": "Fotor"
7
7
  },
@@ -11,6 +11,7 @@ export const PACKAGE_ROOT = fileURLToPath(new URL('../', import.meta.url));
11
11
  export const ENDPOINT = 'https://mcp.fotor.com/mcp';
12
12
  export const CALLBACK_HOST = '127.0.0.1';
13
13
  const execute = promisify(execFile);
14
+ const CALL_TIMEOUT_SECONDS = 300;
14
15
  export function supportedNode(version) {
15
16
  const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(version);
16
17
  return !!match && ((Number(match[1]) === 24 && Number(match[2]) >= 2) || Number(match[1]) === 26);
@@ -68,7 +69,7 @@ export async function resolveMcp(input = {}, options = {}) {
68
69
  const endpoint = serviceUrl(suppliedArgs?.[1] ?? input.endpoint ?? ENDPOINT);
69
70
  const callbackPort = input.callbackPort ?? 3335;
70
71
  requireValue(Number.isInteger(callbackPort) && callbackPort > 0 && callbackPort < 65536, 'invalid callback port');
71
- const args = suppliedArgs ? [...suppliedArgs] : [proxy, endpoint, String(callbackPort), '--host', CALLBACK_HOST, '--transport', 'http-only', '--resource', endpoint, '--auth-timeout', '600', '--connect-timeout', '20', '--headers-timeout', '20', '--body-timeout', '20'];
72
+ const args = suppliedArgs ? [...suppliedArgs] : [proxy, endpoint, String(callbackPort), '--host', CALLBACK_HOST, '--transport', 'http-only', '--resource', endpoint, '--auth-timeout', '600', '--connect-timeout', '20', '--headers-timeout', String(CALL_TIMEOUT_SECONDS), '--body-timeout', String(CALL_TIMEOUT_SECONDS)];
72
73
  requireValue(!args.some(value => ['--allow-http', '--skip-resource-parameter', '--debug'].includes(value)), 'unsafe or sensitive-output bridge option');
73
74
  const option = name => args[args.indexOf(name) + 1];
74
75
  requireValue(args.includes('--resource') && option('--resource') === endpoint, 'preserve the MCP resource parameter');
@@ -85,7 +86,7 @@ export async function resolveMcp(input = {}, options = {}) {
85
86
  return {
86
87
  client,
87
88
  native: { ...nativeInput, transport: 'stdio', serverName: input.serverName ?? 'fotor', command, args, env, cwd,
88
- toolCallTimeoutMs: input.toolCallTimeoutMs ?? 25000, failOnStartupError: input.failOnStartupError ?? true, reconnect: { ...input.reconnect, enabled: false } },
89
+ toolCallTimeoutMs: input.toolCallTimeoutMs ?? CALL_TIMEOUT_SECONDS * 1000, failOnStartupError: input.failOnStartupError ?? true, reconnect: { ...input.reconnect, enabled: false } },
89
90
  };
90
91
  }
91
92
  /** Share desktop routing, but never copy ambient account credentials into the child. */
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: fotor-audio
3
+ description: Create a soundtrack for an image or video, generate a new track from reference audio, extend/remix/edit a song, synthesize speech or a scripted podcast, or separate vocals and accompaniment with Fotor.
4
+ ---
5
+
6
+ # Fotor Audio
7
+
8
+ Discover the requested tool through the [MCP connection](references/mcp-integration.md#connection). Use `list_models(media_type="audio", mode=...)` for the chosen operation, then inspect a returned `model_id`. Its `operations[]` describes the selector, parameters, limits and output. Match these to the current tool schema. Only the soundtrack tool accepts a caller-selected model. If a required input is missing, ask for it before submitting.
9
+
10
+ ## Choose the operation
11
+
12
+ | Request | Tool and selector | Required inputs and result |
13
+ | --- | --- | --- |
14
+ | Compose music for a photo or clip | `submit_soundtrack_task`, discovery mode `soundtrack` | Provide exactly one of `image_url` or `video_url`. Optional music description and model. The output is a separate MP3. The tool does not mix it into the video. |
15
+ | Generate a new vocal or instrumental track | `submit_audio_track_task`, `track` | Provide `audio_url`, a supported `generate_type` and a style `prompt`. Use `vocal_gender` only for `Vocals`. |
16
+ | Extend a song | `submit_song_edit_task`, `songextend` → `operation=extend` | Provide `audio_url`, lyrics, positive `extend_at_ms`, and `extend_type` of `head` or `tail`. |
17
+ | Remix a song | Same tool, `songremix` → `operation=remix` | Provide `audio_url`, lyrics and a new arrangement prompt. Source music must be MP3/M4A, 10–350 seconds, with a detectable beat. |
18
+ | Edit a section of a song | Same tool, `songedit` → `operation=edit` | Provide `audio_url`, lyrics and `edit_start_ms` / `edit_end_ms`. Allow a window of at least 3,000 ms and 12,000 ms of source music on either side. |
19
+ | Read text aloud | `submit_speech_task`, `text2audio` → `mode=tts` | Supply `content` and a supported built-in `voice`. The result is spoken MP3 audio. |
20
+ | Voice a scripted podcast | Same tool, `podcast` → `mode=podcast` | Supply ordered `conversations` with a supported voice and text for each turn. |
21
+ | Extract existing vocals and accompaniment | `submit_audio_separation_task`, `audiostem` | Supply `audio_url`. Deliver the two stems as a downloadable ZIP. |
22
+
23
+ Use integer milliseconds for audio time bounds and only the fields for the selected operation. Verify model-specific length, voice and source-format constraints before submission. Local inputs use the [upload workflow](references/media-upload.md). Pass the confirmed `file_url` or an existing accessible HTTPS source. A task ID cannot substitute for an audio URL. For video generation with reference sound or native output audio, use the video workflow.
24
+
25
+ ## Submit and deliver
26
+
27
+ Give the [credit-consumption notice](references/mcp-integration.md#credit-consumption-before-submission) before submitting once. Follow the [task result workflow](references/mcp-integration.md#submission-recovery-and-results) for immediate results, processing, terminal errors and uncertain submissions. Speech, podcasts and separation can complete in the first response. Report the actual status and deliver the returned MP3 or ZIP link. Preserve its format from the originating operation if a later query omits it. A completed response with no URL has no deliverable link.
@@ -0,0 +1,68 @@
1
+ ---
2
+ platform: dsh
3
+ ---
4
+
5
+ # DeepSeek Harness authentication and browser access
6
+
7
+ DeepSeek Harness is abbreviated as `dsh` in commands and native identifiers.
8
+
9
+ ## Ownership and baseline
10
+
11
+ The current acceptance baseline is Linux DeepSeek Harness Web `0.2.1-rc.3`, with package-manager-owned `mcp-remote 0.15.2` and stable Node `>=24.2.0 <25.0.0 || 26.x`. Historical rc.2 results retain their original scope; matching the declared host range alone is not acceptance. DeepSeek Harness owns the stdio client and tool permissions; the bridge owns OAuth and its credential store. Do not describe this as native remote OAuth in DeepSeek Harness. Desktop, headless and ACP have separate acceptance scopes.
12
+
13
+ Use this guide with the [shared runtime workflow](mcp-integration.md#runtime-workflow). Installation, authorization, actual calls, website access, restart reuse and reauthorization recovery are distinct outcomes. Do not infer full support from one successful call.
14
+
15
+ ## Installation and automatic configuration
16
+
17
+ For installation, source changes, missing dependencies, or invalid saved paths, read the installed package README and `INSTALL.md`. GitHub installation obtains the pinned bridge through the package manager; npm carries its full dependency tree. Node remains external.
18
+
19
+ From 0.6.1, select the installed Bundle with Web **Enable now** or load its CLI profile. Host activation enables both adapters by default. `fotor-skills` resolves this package's skills and uses the native filesystem provider without default-root scanning. `fotor-mcp` resolves Node and both installed bridge entrypoints, then supplies complete native stdio configuration. Runtime defaults are not written into a user patch. A package download alone runs no hook or authorization.
20
+
21
+ Explicit profile/home/launch overrides, including disabled states and the external `MCP_REMOTE_CONFIG_DIR`, take precedence. Do not replace them or clear credentials to repair a path error. An obsolete path requires a targeted native configuration edit: remove only that override to adopt automatic resolution, or correct it. Conflicting Fotor services or skill providers require resolving the duplicate while preserving the existing installation.
22
+
23
+ Use native `root`, `list` and `why` for diagnostics; do not guess pnpm store paths. The skill provider's running state alone is not discovery: verify the actual Fotor entries and their installed resource paths. Use native `read` for skill references; the Linux Shell sandbox can hide host paths. Do not scan unrelated packages after a native read failure.
24
+
25
+ ## First authorization
26
+
27
+ Enabling MCP starts one cancellable connection task. The adapter runs the installed mcp-remote client with the same credential directory, endpoint, resource, callback and security arguments as the proxy. The bridge reuses valid credentials or opens the ordinary browser for user login and consent. Fotor code does not read tokens, implement OAuth, or install dependencies during connection. Model-provider login is separate.
28
+
29
+ Confirm the opener uses the user's daily ordinary browser; retain its profile and login state. A task-specific routing override may be used without changing the system default; record it separately from untouched default-browser behavior. Human authorization still belongs to the user, including Continue / Wait / Cancel. The adapter's states and sanitized diagnostics distinguish `preparing`, `waiting-authorization`, `connected`, `failed` and `stopped`; an active adapter is not proof of a connected MCP service.
30
+
31
+ After Continue, require successful client connection and actual tools discovery. The client and callback listener must exit before the native MCP client starts the proxy. Proxy tool discovery completes readiness; a consent success page or zero client exit alone is insufficient. Authorization waits at most ten minutes. Cancel by disabling `fotor-mcp` through the native plugin controls; the owned child and callback must stop without blocking the Web interface. A cancelled or failed task waits for a deliberate disable/enable before another authorization attempt.
32
+
33
+ After connection, use `/fotor-connect` or the native skill tool for the actual discovered entry. Verify with a read-only `list_models` call when requested. MCP-only requests neither request a website link nor query credits. Installation, authorization, discovery and actual queries are distinct evidence.
34
+
35
+ ## Website access
36
+
37
+ Prepare the user's daily ordinary browser before requesting a short-lived link. Preserve its existing Fotor login state; do not sign out, replace its profile or clear data to manufacture a fresh-login test. Confirm the intended browser/profile can be targeted before calling `get_website_url`.
38
+
39
+ Follow [one-time browser link rules](mcp-integration.md#one-time-browser-links): validate the production handoff endpoint and returned expiry, then open the exact original link once. A missing `target_url` must be reported truthfully, not invented. Do not prefetch, preview, rewrite or repeat a consumed link.
40
+
41
+ Use an available host opener and the exact confirmed daily browser profile. If the DeepSeek Harness shell sandbox prevents desktop access, request native approval for that single command with a clear purpose; do not change the session's standing permissions. A background browser job may need a result check for that same job, which must not launch the link again. Do not add browser diagnostics or a temporary web proxy.
42
+
43
+ If automatic opening is unavailable, provide the unconsumed original link in the native conversation for the user to open once in that browser. Record this as manual opening. Wait for confirmation of the final production website and login state. A successful command or a pre-existing signed-in page does not prove a signed-out-to-signed-in transition. Report MCP and website results separately, then introduce the main capabilities.
44
+
45
+ ## Bounded recovery and controlled reauthorization
46
+
47
+ Use the shared two-retry limit, waits of two/five seconds and ninety-second automatic-stage budget. Human login time is excluded. Include the bridge's own actions in the record; do not add a second retry or OAuth loop. Disabling DeepSeek Harness reconnect does not guarantee the bridge will never open a new authorization page internally.
48
+
49
+ On an authorization failure, cancellation, permission denial or unknown state, stop the current call. Do not treat a login-page CORS/preflight rejection as the same failure as missing OAuth discovery state. A missing-discovery-state message does not prove that the issuer actually changed.
50
+
51
+ For user-requested reauthorization, use this single sequence:
52
+
53
+ 1. Stop the failed operation, this profile's proxy and any leftover callback listener. Do not start a competing authorization flow.
54
+ 2. Preserve the same credential directory and connection/security arguments. Do not read, copy or edit tokens.
55
+ 3. Re-enable the MCP adapter after the user requests another connection attempt. It runs the standalone authorization client and applies the same Continue / Wait / Cancel handling and native-result verification.
56
+ 4. Stop the standalone client, restart the configured DeepSeek Harness MCP and prove recovery with an actual read-only query. A successful consent page without that query is not recovery.
57
+
58
+ A cached client connection without a new consent flow is reuse, not invalid-grant recovery. Never clear a global authorization directory, substitute a new empty store, weaken issuer/resource/PKCE/TLS checks or sign out the daily website to force a test. Server-side invalid-grant acceptance requires a real failure or an available native operation limited to this exact temporary grant. If no safe trigger exists, report that recovery scope as unverified. Expiry-driven refresh likewise requires actual evidence.
59
+
60
+ An explicitly user-approved isolated local-cache-loss test is a separate acceptance scope. After stopping all task-owned processes and callbacks, verify ownership and ordinary-file type before removing only that connection's token cache, without reading its contents. Keep the original directory, registration and connection parameters. Re-enable the adapter for user consent, then require an actual query and another query after a full restart. Label this local credential-loss recovery; it does not establish server-side revocation, expiry or intact rejected-cache recovery.
61
+
62
+ ## Updating and removing
63
+
64
+ Use the native Bundle commands in the package README. After updating, inspect the resolved source, version, file contents and actual skill directory; package-manager links outside the package are distinct from forbidden symlinks inside its resources. Keep only one enabled Fotor skill source. Re-resolve the managed bridge path when replacing a package; preserve the external credential store.
65
+
66
+ Disable this Bundle before native removal. Retain its external overrides and credentials unless the user explicitly requests a targeted removal. Cleanup of an isolated acceptance environment may delete that environment's local store after all related processes stop; that does not revoke server-side consent. Leave daily installations, credentials and browser login unchanged. Keep package, model-session, bridge, website, reuse and recovery evidence separate.
67
+
68
+ Reinstalling the same source/profile with the same credential directory can reuse accepted authorization. It still establishes a new connection, so verify actual discovery and a requested read-only query. Changing profile, home, credential directory or connection parameters can select another cache. Preserve explicit disabled settings and valid complete configuration when upgrading; correct only obsolete path overrides through native configuration.
@@ -0,0 +1,11 @@
1
+ # Fotor credit balance
2
+
3
+ ## Query the selected account
4
+
5
+ 1. When the user requests their own balance, follow [MCP authentication](mcp-integration.md#authenticate-mcp). Reuse valid authorization and discover `get_credits`. If it is unavailable, report that and stop.
6
+ 2. Call `get_credits` without arguments. The authenticated session identifies the account. Report only the nonnegative numeric `credits` value, including zero, and finish. A balance query needs no website visit.
7
+ 3. If authentication fails, the service reports an error, or the balance is missing or invalid, report it as unavailable. An unknown balance is not zero. Never infer a balance from task consumption.
8
+
9
+ ## Insufficient credits during media submission
10
+
11
+ When a submission explicitly reports `insufficient_credits`, explain that the task could not proceed for that reason. Retain any known task ID and reported consumption, stop dependent operations, and finish without extra links, a balance query or another submission. A lost response is a different outcome; follow [task recovery](mcp-integration.md#submission-recovery-and-results).
@@ -0,0 +1,140 @@
1
+ # Fotor MCP Integration
2
+
3
+ ## Connection
4
+
5
+ This **production release channel** package connects to the **production service** at `https://mcp.fotor.com/mcp` using Streamable HTTP. Both release channels use the production account, website, and credits. Preserve this service throughout a task and its assets.
6
+
7
+ | Environment | MCP endpoint | Website target | Login handoff endpoint |
8
+ | --- | --- | --- | --- |
9
+ | production | `https://mcp.fotor.com/mcp` | `https://www.fotor.com/` | `https://api.fotor.com/api/user/mcp/browser-handoff` |
10
+
11
+ Package checks cover files, references, and configuration. Verify installation, MCP authorization and calls, website login, credit links, uploads, and media execution separately in the selected host and environment. A release or model query does not establish successful website login or completed media results.
12
+
13
+ Use the runtime routing, authentication, and website flow below. Keep credentials in the client's supported store and report actual outcomes for the requested operation.
14
+
15
+ ## Runtime workflow
16
+
17
+ ### Route the request
18
+
19
+ | Intent | Action |
20
+ | --- | --- |
21
+ | Connect to Fotor, connect to the Fotor website, or connect and open Fotor | Authenticate MCP, then follow the website flow below |
22
+ | Connect to Fotor MCP or check MCP connectivity without a website request; explicitly keep the website closed | Perform the requested MCP check; omit the website handoff |
23
+ | Introduce features or query models | Answer from current tool descriptions or model queries; omit website navigation unless also requested |
24
+ | The user asks for their own Fotor credit balance | Follow the [credits workflow](credits.md); ordinary connection does not query balance |
25
+
26
+ Equivalent wording in other languages follows the same routing. Uploads, image processing, and media generation alone do not request website access. Ordinary website connection requests authorize the final visible navigation; they do not authorize media submissions.
27
+
28
+ ### Authenticate MCP
29
+
30
+ Authentication belongs to the native host client except in DeepSeek Harness, where the separately installed bridge owns OAuth and credential storage. Follow the packaged [authentication guide](authentication.md) for that owner and its status, authorization and recovery entrypoints. The shared gates below still apply; DeepSeek Harness's standalone authorization client must finish before its stdio proxy starts.
31
+
32
+ 1. Confirm the installed endpoint and enabled state. Both release channels require the production MCP endpoint in the Connection section. If the package or a host override selects another service, stop and explain that the installation/configuration needs updating through the host's controls; do not contact that service, silently change endpoints, or migrate its credentials. If Fotor tools are absent or a call fails authentication, diagnose native authorization before choosing a reload/new-chat fallback. Follow the packaged [authentication guidance](authentication.md) for native status, permission recovery, and login routes, including when Fotor remote tools are unavailable. Reuse usable production credentials through the host's supported MCP client. A confirmed missing/invalid authorization enters OAuth; unknown status remains inconclusive and uses the explicit choice in that workflow after bounded diagnosis. If the user forbids all browser use and authentication is needed, explain that requirement and stop. Otherwise, start OAuth only for missing/invalid credentials or explicit reauthorization, preserving existing credentials on network errors.
33
+ 2. When OAuth is needed, start the documented authentication owner's supported login flow for the selected server and open its authorization URL in an external browser. Let the user complete login and consent. If external-browser automation is unavailable, explain that limitation and give the user the authorization link to open externally; keep the callback flow active. Do not silently use the in-app browser for OAuth.
34
+ 3. After opening the external authorization page or supplying the manual external link, collect the [OAuth completion choice](#oauth-completion-choice). Keep the callback flow active while awaiting the answer.
35
+ 4. When this request started OAuth, proceed only after an explicit continue choice and client-confirmed authorization success. If the callback is pending, explain the delay and wait within the client's login timeout. OAuth cancellation, login expiry, or denied authorization stops the flow before website handoff. A user reporting completion or a login page loading is not proof that credentials were obtained.
36
+ 5. After credential reuse or successful OAuth, establish a usable connection in the client serving this request and discover the authenticated tools. Apply [bounded connection recovery](#bounded-connection-recovery) to eligible transient failures; a successful OAuth result alone does not establish tool availability. Keep credential values in the client's store, outside conversation output, files, and logs.
37
+
38
+ For an MCP-only health check, call `list_models` when discovered and report its actual outcome. If a successful discovery omits it, report the unavailable probe without assuming authentication failed; uploads and the new website-login tool can remain available while generation and credits tools are disabled. A failed or incomplete discovery is a connection problem, not proof that a tool is absent. Installation and discovery alone do not establish a successful call. Do not request upload addresses, transfer files, submit media, query arbitrary tasks, or call `get_credits` or `get_website_url` for a read-only health check.
39
+
40
+ ### OAuth completion choice
41
+
42
+ Use the host's structured question/choice UI when available to ask whether the user has completed external login and authorization; otherwise offer the same choices conversationally. Localize the question and labels to the conversation language. For a website connection, use the Continue label and browser route from the packaged [authentication guidance](authentication.md); the shared actions below remain the same.
43
+
44
+ | Choice | Next action |
45
+ | --- | --- |
46
+ | Signed in and authorized; continue to Fotor in the selected browser | Verify client-confirmed OAuth success, then continue the website flow. |
47
+ | Not finished; keep waiting | Keep the current callback active within its timeout and wait for the user to explicitly choose to continue. |
48
+ | Cancel connection | Stop this connection attempt and cancel the pending login through the client when supported. Preserve credentials already stored; cancellation does not request logout or revocation. |
49
+
50
+ A preselected option, no answer, elapsed time, or a successful callback alone does not select Continue. Request `get_website_url` only after both user continuation and client success, so its short-lived ticket is not created while waiting for a choice. If structured input is unavailable, present the same choices in text and wait for an explicit reply. If the user reports an error, report the failed authorization and stop rather than treating the answer as completion.
51
+
52
+ Skip this prompt when the request reuses valid credentials without starting OAuth. For an MCP-only check or another task requiring authentication, replace the first label with "Signed in and authorized; continue the requested task" and preserve the original scope; the choice does not add website navigation.
53
+
54
+ ### Bounded connection recovery
55
+
56
+ Apply this policy only to read-only OAuth metadata retrieval, MCP connection/tool discovery, and the `list_models` connection probe. Eligible failures are connection interruptions, request timeouts, temporary HTTP 5xx responses, and errors such as "failed to resolve OAuth metadata before using stored credentials" caused by an HTTP request failure. An OAuth-related network error does not establish invalid credentials. Read-only native authorization diagnosis shares the same retry counter and time budget. First resolve known execution restrictions through host permissions or its connection UI: follow the packaged [authentication and permission guidance](authentication.md); unchanged access restrictions are not transient retries. Other inconclusive results use the remaining limits, then the explicit unknown-state choice rather than silently entering OAuth.
57
+
58
+ 1. Use one retry counter and one **90-second automatic-work budget** for the whole connection/discovery/probe sequence, starting with its first automatic request. After the initial attempt, allow at most **two retries**, waiting **2 seconds** before retry 1 and **5 seconds** before retry 2. Count automatic requests, reconnect/refresh work, and backoff waits. Pause accounting while the user completes external login, answers a connection choice, or decides a host permission request; the client's own OAuth timeout still applies. Preserve spent time and retries across stages, successful intermediate requests, OAuth completion, and refreshes.
59
+ 2. Before another wait or request, check the remaining budget and cancellation state. If the remaining time cannot cover the next backoff, stop rather than shortening the delay. Cap request timeouts to the remaining budget where the host supports it. Stop at the first exhausted limit. If the host cannot interrupt an in-flight request, report any overrun and start no further work after it returns; these skill instructions cannot enforce the host's transport deadline.
60
+ 3. Retain the selected environment, stored credentials, and the user's Continue / Wait / Cancel decision. Briefly report the retry number in the conversation language. Continue does not need another confirmation; Wait keeps continuation pending and Cancel ends it. This loop never restarts OAuth, repeats token exchange, logs out, or clears credentials.
61
+ 4. Retry the failed read-only operation. When initialization or tool availability requires recovery, use an available host-supported refresh/reconnect in the client serving the current request, then rediscover its tools. A separate diagnostic client does not refresh the original chat. Before declaring the host unable to recover, classify native authorization using the [authentication workflow](#authenticate-mcp). Missing remote tools do not rule out a native login command or connection UI. After authorization is classified or completed, if the current host still offers no usable recovery path, report that specific limitation and the reload/new-session next step; do not invent commands, extract tokens, or create an ad hoc credential client.
62
+ 5. Require successful discovery and, when `list_models` is available, a successful call before resuming the requested workflow. A catalog or saved OAuth status alone is insufficient; an empty filtered model result is a valid response. If successful discovery genuinely omits the probe, report that capability gap and retain the existing workflow for available tools. After exhaustion, report the failed stage and retries used without claiming a website connection or assuming the user must log in again.
63
+
64
+ Confirmed invalid credentials, denied permissions, invalid parameters, environment mismatches, certificate-validation errors, and genuinely absent tools are not transient retries. Stop this recovery loop and explain the specific condition; use the supported authorization flow only when missing/invalid credentials or an explicit reauthorization request warrant it. User cancellation stops recovery immediately.
65
+
66
+ This budget covers automatic MCP connection recovery, not website navigation, credit queries, or media execution. Keep website ticket creation and consumption, upload requests/transfers, media submissions, and task queries outside this retry loop. Their existing workflows retain their own stopping conditions; in particular, preserve uncertain submissions and the website-link replacement limit. Credit responses follow the packaged [credits workflow](credits.md).
67
+
68
+ ### Connect to the website
69
+
70
+ 1. Complete MCP authentication and authenticated tool discovery, using [bounded connection recovery](#bounded-connection-recovery) for eligible failures. When available, require a successful `list_models` read-only check without dumping its catalog before requesting a website link. Determine browser availability before creating the short-lived link, following the browser route in the packaged [authentication guidance](authentication.md). Otherwise prepare the manual fallback. Only a successful discovery that omits `get_website_url` establishes a missing website capability; an unavailable chat tool surface or failed discovery does not establish the service version. Report MCP and website outcomes separately, without claiming an ordinary page visit established automatic login.
71
+ 2. Call `get_website_url` without arguments. Its public response contains `handoff_url` and integer `expires_in` from 0 to 600; it does not expose `target_url`. Require a usable link and remaining lifetime greater than zero. A zero lifetime is already expired: use the bounded replacement rule below. Missing, malformed, or out-of-range fields are a handoff failure. The server configures and validates the destination; before navigation, the plugin can check only the handoff endpoint against the [connection table](#connection), not the hidden target. Never decode the ticket, rewrite its URL, or change environments to recover a mismatch.
72
+ 3. Follow [one-time browser links](#one-time-browser-links) for the returned `handoff_url`, using the actual remaining lifetime. This final visible navigation is the requested website visit and consumes the ticket.
73
+ 4. Inspect the resulting page in that same browser session. Compare its HTTPS origin with the selected website in the connection table and verify authenticated state before reporting the website connected. A valid handoff endpoint alone does not prove the hidden redirect target is correct. On a different environment or unexpected origin, stop further interaction and report the mismatch; do not follow it as a fallback. A link, a generic page, or a login/error screen is insufficient. If state is unclear, ask the user to confirm it. Website failure does not justify resetting working MCP credentials.
74
+ 5. Introduce the available main features after the connection attempt and report partial outcomes accurately. Do not automatically list models or query credits; website login works independently of balance and billing-account registration.
75
+
76
+ ### One-time browser links
77
+
78
+ Apply this section only to `get_website_url.handoff_url`. This plugin's selected website connection flow uses one final visible navigation in the browser specified by the packaged [authentication guidance](authentication.md). The service description instead prescribes a user-clicked link to prevent early consumption; the plugin's selected browser action is the intended final visit, never a pre-opening check. Honor an explicit user preference for manual delivery and any host restriction; use the manual fallback when direct navigation is unavailable.
79
+
80
+ - Parse the returned URL before use. It must have the exact HTTPS origin and path of the selected environment's [login handoff endpoint](#connection), no username/password or fragment, and one nonempty `code` query parameter only. Check URL components rather than hostname substrings. Reject an unknown environment or mismatch without fetching the address, rewriting the host, or switching services.
81
+ - Immediately navigate once in the selected visible host browser. Do not first fetch, preview, probe, or open the ticket in a hidden tab. After navigation, treat it as consumed and never offer it as a reusable login link.
82
+ - When the required browser is unavailable, explain the limitation and present the complete unused link with its returned lifetime for immediate manual opening. Manual completion stays pending until confirmed. Honor explicit user restrictions on browsing or link disclosure; do not silently switch browsers.
83
+ - If a link expired or a failed navigation may have consumed it, resolve the cause or establish a manual route before requesting one replacement for the still-requested action. Stop after a repeated failure. Record outcomes without credentials, authorization codes, or one-time URLs in repository files or diagnostic logs.
84
+
85
+ ### Discover capabilities and choose a model
86
+
87
+ Inspect the connected service's actual tool descriptions and input schemas. The table below describes the current contract, not a fixed tool-count requirement. If a required operation is absent, explain the missing capability and provide only a clearly labeled preparation brief when useful.
88
+
89
+ | Tool | Purpose and required decision |
90
+ | --- | --- |
91
+ | `list_models` | Discover model IDs and modes; query a selected ID for its supported parameters and defaults |
92
+ | `get_upload_url` | Obtain a signed PUT address; follow the [upload workflow](media-upload.md) to actually transfer local media |
93
+ | `submit_image_task` | Generate without reference images; edit/reference with `image_urls`; a successful call may consume Fotor credits |
94
+ | `submit_image_upscale_task` | Upscale `image_url` with an optional positive ratio; no model ID or prompt; a successful call may consume Fotor credits |
95
+ | `submit_background_removal_task` | Remove the background from `image_url`; no model ID or prompt; a successful call may consume Fotor credits |
96
+ | `submit_text_to_video_task` | Generate video from a text prompt; a successful call may consume Fotor credits |
97
+ | `submit_first_frame_video_task` | Animate `image_url` as the first frame; a successful call may consume Fotor credits |
98
+ | `submit_first_last_frame_video_task` | Use ordered `start_image_url` and `end_image_url`; a successful call may consume Fotor credits |
99
+ | `submit_multimodal_video_task` | Use supported image, video, and/or audio references; a successful call may consume Fotor credits |
100
+ | `submit_soundtrack_task` | Compose a separate MP3 from exactly one source image or video |
101
+ | `submit_audio_track_task` | Generate a new track from reference audio |
102
+ | `submit_song_edit_task` | Extend, remix or edit a section of a song |
103
+ | `submit_speech_task` | Generate speech or a scripted podcast with built-in voices |
104
+ | `submit_audio_separation_task` | Separate existing vocals and accompaniment into a ZIP |
105
+ | `get_task` | Look up one known image, video or audio task using existing credentials |
106
+ | `get_website_url` | Obtain an environment-bound, one-time website login link for the verified MCP user |
107
+ | `get_credits` | Query only the authenticated user's own balance; follow the [balance lookup](credits.md#query-the-selected-account) |
108
+
109
+ For model-based generation/editing, start with `list_models`, optionally filtering by `media_type` and `mode`. Uploads and fixed image-processing operations use their own tool contracts without model selection. Filters combine with AND; an empty filtered result is not evidence of a failed connection. Then query `list_models` with the chosen `model_id` before submitting. Model IDs, available modes, and catalog sizes can change; an unknown or retired ID requires a new selection, not an invented replacement.
110
+
111
+ For standalone audio, read the selected model’s `operations[]`. Use its tool, selector, required parameters, result format and synchronous behavior. Only soundtrack creation accepts a model ID.
112
+
113
+ For images and videos, use the returned resolutions, aspect ratios, qualities, duration values/ranges, reference types, and defaults. Honor an explicit model or output preference; explain an unsupported constraint before changing it. When no preference is given, choose a suitable supported model and use its reported defaults. `duration=0` selects `default_duration`; duration ranges are inclusive integer seconds, while a list permits only its listed values. `explicit_aspect_ratio_modes` requires a concrete supported ratio instead of `auto`; for multimodal references this condition applies when images are supplied without videos.
114
+
115
+ ### Inputs and native capabilities
116
+
117
+ Generation references and image-processing inputs must be accessible HTTPS URLs. For local files and client-accessible attachments, follow the shared [media upload workflow](media-upload.md). Use the successful upload's `file_url`, never its signed `upload_url` or a filesystem path, as a task input. Preserve the selected environment and ordered references, including first/last frames. Storage acceptance does not establish the model's input compatibility.
118
+
119
+ Use native model resolutions and supported output options for generation. Explicit image upscaling uses `submit_image_upscale_task`; its current positive, finite ratio defaults to 2 and its output width and height are capped at 2048 pixels. Background removal uses `submit_background_removal_task` for a transparent image. Neither fixed operation requires a model ID or prompt. These tools do not establish masks, video upscaling, timeline/range editing, or dubbing. Run a sequence of operations only when requested, waiting for each required result before the next submission.
120
+
121
+ ### Credit consumption before submission
122
+
123
+ Every discovered tool whose name matches `submit_*_task` may consume Fotor credits when its call succeeds. This applies to all image, video and audio submissions, including future tools matching that name pattern; discovery and the actual schema still determine whether a tool can be called.
124
+
125
+ Before submitting, briefly tell the user in their conversation language that the successful call may consume Fotor credits. Continue under an already explicit task request without adding a blanket confirmation step. Preserve the user's budget, requested scope, and host approval requirements. For an explicitly requested sequence, one notice before the first submission may cover every named step; disclose newly added steps or scope changes before submitting them.
126
+
127
+ Do not apply this notice to model discovery, balance queries, uploads or task polling, and do not add a preliminary balance query to a media request. Do not invent a price, guarantee a charge, or equate accepted submission with completed media. Preserve zero and unknown `credits_increment` values and never add repeated observations as separate charges. Uncertain submissions still follow the no-automatic-resubmission rule below.
128
+
129
+ ### Submission, recovery, and results
130
+
131
+ For an explicit `insufficient_credits` submission error, follow [insufficient credits during media submission](credits.md#insufficient-credits-during-media-submission). This applies to image generation, fixed image processing, and every video and audio submission mode; it does not make balance queries a prerequisite.
132
+
133
+ 1. Submit once. Retain the returned task ID, environment, selected operation and expected output format. Image and video calls normally return an accepted task. Audio may already have completed. Inspect both the MCP error flag and the structured content, including on `isError=true`. Retain any known task ID, safe `failure_reason` and reported credit value.
134
+ 2. On completion, deliver the actual `result_url` immediately without polling. Prefer a host-supported preview for playable media. Offer an audio separation ZIP as a download. If the URL is absent, report completion without an available link. Describe quality only after inspecting the artifact.
135
+ 3. For an accepted or processing task, query the same ID with `get_task`. Each call performs one lookup. Within the task budget, wait between checks. The query can omit the model and result format, so retain the originating operation. Stop on completion, `failed`, `timed_out` or `cancelled`. Report unknown or conflicting state as uncertain. A safe failure summary may be generic.
136
+ 4. A transport timeout, lost response or `submission_uncertain` may follow an accepted, chargeable submission. Recover only by looking up a known ID. Without an ID, report the uncertain outcome and stop. Never automatically resubmit. On a lookup error or polling limit, preserve the ID and last observed state.
137
+
138
+ `credits_increment` reports the increment returned by that particular submission or query, not a balance or a price quote. Preserve `0` as zero and `null` as unknown. Do not add submission and polling values together as if each observation were a new charge. Report missing or inconsistent values without estimating usage.
139
+
140
+ Task lookup is scoped to the selected API key's Business. Another Business cannot retrieve its results, and a task ID must not be moved between environments to recover a failure. Task lookup uses existing credentials. If none are usable, report `credentials_unavailable`. It creates no developer, key or task and consumes no credits. Use `list_models` for connection checks.
@@ -0,0 +1,34 @@
1
+ # Fotor Media Upload
2
+
3
+ Read this workflow for standalone uploads and when an image, video or audio task needs local references. Use already accessible HTTPS references directly for creation; upload only the specific local files or client-accessible attachments needed by the user's request. An attachment label without readable bytes is not an uploadable file.
4
+
5
+ ## Prepare the input
6
+
7
+ 1. Follow [MCP authentication](mcp-integration.md#authenticate-mcp), preserving the installed environment. Discover `get_upload_url` before attempting an upload. Uploads need no model selection and can be available even when model discovery or generation tools are absent. An upload request does not request a website handoff.
8
+ 2. Confirm the file can be read by the client that will send its bytes. Determine its basename, actual media type, and exact nonzero byte size. Pass only the basename, including its extension, as `file_name`, and an integer as `size_bytes`.
9
+ 3. Check the service's supported type and configured size limit. The current upload contract accepts the extensions below, case-insensitively; SVG, documents, and archives are unsupported. An extension determines the signed Content-Type, but does not validate the file's contents or prove that a selected generation model accepts it. Apply the model's additional format/reference constraints when preparing creation inputs.
10
+
11
+ | Media | Supported extensions |
12
+ | --- | --- |
13
+ | Image | `jpg`, `jpeg`, `png`, `webp`, `gif`, `bmp`, `avif`, `heic`, `heif` |
14
+ | Video | `mp4`, `mov`, `webm`, `m4v`, `avi`, `mkv` |
15
+ | Audio | `mp3`, `wav`, `m4a`, `aac`, `ogg`, `flac`, `opus` |
16
+
17
+ Service limits can change. Report a size/type rejection before continuing; do not silently convert, compress, or replace the user's file. If the tool is absent or storage is unconfigured, explain that upload is unavailable. For creation, an appropriate accessible HTTPS reference is a possible user-supplied alternative.
18
+
19
+ ## Transfer and confirm
20
+
21
+ 1. Call `get_upload_url` with the checked `file_name` and `size_bytes` only when the client is ready to send the file. Require the returned `upload_url`, `file_url`, `method`, `headers`, and positive `expires_in`; the current method is `PUT`.
22
+ 2. Use a client-supported HTTP/file-transfer capability to PUT the unchanged raw bytes to `upload_url`, applying only the returned headers. Send neither multipart/form-data nor Fotor OAuth credentials. A browser using File/Blob supplies Content-Length itself; a shell/HTTP client must preserve the exact signed byte count and Content-Type. Do not fetch, preview, or follow a redirect from the signed upload address.
23
+ 3. Keep signed URLs in transient tool state. Avoid command tracing, verbose HTTP output, and errors that echo the full signed URL; never record it in repository files or diagnostic logs. Use the returned address unchanged rather than reconstructing its signature or host.
24
+ 4. Confirm an actual upload response with a 2xx status before marking the file uploaded or passing `file_url` to another tool. Requesting the address alone does not transfer bytes, and a returned `file_url` is not proof that the object exists. Report inability to send the file when the host lacks the required capability.
25
+
26
+ If the file changes after signing, recalculate its metadata and request a new link. A timeout with no response leaves upload success unconfirmed. Within the active request, allow at most one retry per file after resolving the cause: PUT the same unchanged bytes to the still-valid address, or obtain a new link if expired. The upload address permits repeated PUTs to the same object during its lifetime; it is distinct from the one-time website handoff. Stop after another failure and report the file as unsuccessful; do not let dependent creation proceed with that URL. This upload retry rule does not authorize retrying an uncertain media-task submission.
27
+
28
+ ## Deliver or continue
29
+
30
+ Process multiple files one at a time, preserving input order and the association between each file and its successful URL. Report name, media type, exact byte size, and `file_url` for successes; report a concise reason for each failure without exposing signatures. A partial batch is not an all-success result. If a creation task needs a failed input, resolve it before submission rather than silently omitting it.
31
+
32
+ For standalone uploads, deliver those results and finish. For requested creation, use the uploaded URLs in the appropriate reference fields or the selected audio operation’s source URL or image-processing `image_url`, keeping the same environment. File acceptance by storage does not establish model compatibility or media-task success.
33
+
34
+ `expires_in` describes the maximum upload-address lifetime; temporary signing credentials may expire earlier. It does not describe file retention. Signature expiry does not delete an uploaded file, and `file_url` is not a presigned download URL. Do not promise permanent storage, a deletion time, or long-term URL availability unless the service provides that information.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: fotor-connect
3
- description: Connect to the Fotor website, check only its MCP connection, introduce its features, or query models and parameters. Use for Fotor connection, website access, and capability requests; media creation/processing belongs to fotor-image or fotor-video and standalone uploads belong to fotor-upload and credit-account questions belong to fotor-credits.
3
+ description: Connect to the Fotor website, check only its MCP connection, introduce its features, or query models and parameters. Use for Fotor connection, website access, and capability requests; media creation/processing belongs to fotor-image, fotor-video or fotor-audio and standalone uploads belong to fotor-upload and requests for the user's own credit balance belong to fotor-credits.
4
4
  ---
5
5
 
6
6
  # Fotor Connection and Features
@@ -23,6 +23,6 @@ These intent rules also apply to equivalent wording in other languages. An expli
23
23
 
24
24
  ## Explain features and models
25
25
 
26
- For the starter prompt, "Connect to Fotor and introduce its main features.", complete the website connection flow and give a brief feature overview: local image/video/audio uploads, image generation/editing, standalone image upscaling and background removal, video generation from supported inputs, querying submitted tasks, and credit balance checks under the packaged credit policy, limited to tools actually available. Mentioning credits does not call `get_credits`. Report MCP and website outcomes separately if either is incomplete. Describe supported capabilities without claiming successful media execution.
26
+ For the starter prompt, "Connect to Fotor and introduce its main features.", complete the website connection flow and give a brief feature overview: local image/video/audio uploads, image generation/editing, standalone image upscaling and background removal, video generation from supported inputs, soundtrack and track creation, song editing, speech/podcasts, vocal separation, querying submitted tasks, and checking the authenticated user's own credit balance, limited to tools actually available. Mentioning credits does not call `get_credits`. Report MCP and website outcomes separately if either is incomplete. Describe supported capabilities without claiming successful media execution.
27
27
 
28
28
  For a model question, use `media_type` and `mode` filters, then query the selected `model_id` for supported parameters and defaults. Show model lists when requested; an internal connection probe does not require displaying its catalog. An empty filtered catalog means no matching models, not a failed connection.
@@ -1,36 +1,11 @@
1
- # Fotor Credits and Top-up
2
-
3
- Read this workflow for a balance question or an explicit recharge request. Media submission and ordinary website connection do not require a preliminary balance query.
1
+ # Fotor credit balance
4
2
 
5
3
  ## Query the selected account
6
4
 
7
- 1. Follow [MCP authentication](mcp-integration.md#authenticate-mcp) for the installed environment, reusing valid credentials or completing required external-browser OAuth. Discover `get_credits`; if absent, report the unavailable capability without changing environments.
8
- 2. Call `get_credits` without arguments. It returns nonnegative numeric `credits` and a regular pricing-page `top_up_url`. This URL reuses an existing browser session but does not sign the user in. It is not a one-time ticket and has no `expires_in` field.
9
- 3. Report the actual balance. `credits_increment` in a task response is that task's consumption, not this balance; do not infer available funds from it. A balance observation is not a generation price quote or a guarantee that a later submission can proceed.
10
- 4. Treat `credits_unavailable`, authentication errors, invalid/missing balance values, and other failures as unavailable information, never as zero. Do not create accounts, keys, replacement tasks, or credentials to work around a balance error. If a successful response has a valid balance but an unusable pricing link, report the balance and, when a link is selected below, the separate link problem.
11
-
12
- ## Select the response
13
-
14
- | Request and result | Action |
15
- | --- | --- |
16
- | Balance below 100, or an explicit request to top up | Report the balance and deliver the validated pricing link as described below. Let the user click it. |
17
- | Balance of 100 or more; no top-up request | Report only the balance. Keep the returned link out of the response. |
18
- | Explicit balance-only or no-link instruction | Report only the balance, including when it is below 100. |
19
- | Browser navigation is forbidden or unavailable | Deliver the selected link if the user permits links; link delivery needs no browser automation. |
20
- | Query failed | Report the failure; do not infer a low balance or invent a pricing link. |
21
-
22
- ## Validate and deliver pricing links
23
-
24
- Use this rule for both `get_credits.top_up_url` and a submission error's `top_up_url`:
25
-
26
- 1. Require a nonempty absolute HTTPS URL whose origin exactly matches the selected environment's website in the [connection table](mcp-integration.md#connection), with no embedded username/password. Check URL components rather than hostname substrings. Reject an unknown environment, malformed URL, or origin mismatch without visiting it, changing environments, or rewriting its host.
27
- 2. Use the exact returned URL as the Markdown target, with a label meaning "View Fotor plans" in the conversation language. Preserve its path, query, and fragment; the login handoff endpoint, `code` parameter, expiry, and single-consumption rules do not apply to ordinary pricing links. If the link is missing or invalid, explain that the pricing entry is unavailable instead of constructing a replacement.
28
- 3. Let the user click the link. A balance or recharge request alone does not call `get_website_url`, open a browser, or refresh a supposed ticket. If the user also explicitly requests a signed-in website session, complete the [website connection flow](mcp-integration.md#connect-to-the-website) separately, then provide the pricing link for them to open in that same browser.
29
-
30
- Leave plan selection and payment to the user. A link or a loaded page does not establish website login, a completed payment, or an increased balance. Keep credentials and website-login tickets out of files and diagnostic logs.
5
+ 1. When the user requests their own balance, follow [MCP authentication](mcp-integration.md#authenticate-mcp). Reuse valid authorization and discover `get_credits`. If it is unavailable, report that and stop.
6
+ 2. Call `get_credits` without arguments. The authenticated session identifies the account. Report only the nonnegative numeric `credits` value, including zero, and finish. A balance query needs no website visit.
7
+ 3. If authentication fails, the service reports an error, or the balance is missing or invalid, report it as unavailable. An unknown balance is not zero. Never infer a balance from task consumption.
31
8
 
32
9
  ## Insufficient credits during media submission
33
10
 
34
- When an image-generation, image-processing, or video submission explicitly returns `insufficient_credits`, report that error. If its `top_up_url` is non-null and valid, deliver it using the pricing-link rules above unless the user prohibited links. Missing or invalid links do not change the error into a balance value; no extra balance query is required.
35
-
36
- Stop dependent operations and retain any task ID returned. Do not automatically resubmit, infer that payment completed, or turn the error into `submission_uncertain`. A lost response or an explicit uncertain-submission result still follows the [task recovery workflow](mcp-integration.md#submission-recovery-and-results).
11
+ When a submission explicitly reports `insufficient_credits`, explain that the task could not proceed for that reason. Retain any known task ID and reported consumption, stop dependent operations, and finish without extra links, a balance query or another submission. A lost response is a different outcome; follow [task recovery](mcp-integration.md#submission-recovery-and-results).