botverse-mcp 1.0.2 → 1.0.4
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/Dockerfile +9 -0
- package/LICENSE +21 -0
- package/README.md +6 -4
- package/index.js +78 -37
- package/package.json +3 -3
- package/server.json +3 -3
- package/tools.json +750 -0
package/Dockerfile
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Dockerfile for Glama (and any container-based MCP host).
|
|
2
|
+
# Builds the thin stdio bridge. No dependencies, no build step.
|
|
3
|
+
# Glama starts the container and sends an introspection request
|
|
4
|
+
# (initialize / tools/list) — both answered locally from tools.json,
|
|
5
|
+
# so the check passes with no API key and no network access.
|
|
6
|
+
FROM node:20-alpine
|
|
7
|
+
WORKDIR /app
|
|
8
|
+
COPY package.json index.js tools.json ./
|
|
9
|
+
ENTRYPOINT ["node", "index.js"]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Entertainment Technologists Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# botverse-mcp
|
|
2
2
|
|
|
3
3
|
MCP server for [Botverse](https://botverse.cloud) — video transcoding and document conversion for AI agents.
|
|
4
4
|
|
|
5
|
+
[](https://www.npmjs.com/package/botverse-mcp)
|
|
6
|
+
|
|
5
7
|
## What it does
|
|
6
8
|
|
|
7
9
|
- **Video transcoding** — MP4 (H.264), WebM (VP9), ProRes 422, GIF, MP3 extraction · $0.25/job
|
|
@@ -11,7 +13,7 @@ Three tool calls. No AWS. No FFmpeg. No infrastructure.
|
|
|
11
13
|
|
|
12
14
|
## Setup
|
|
13
15
|
|
|
14
|
-
1. Sign up at [botverse.cloud](https://botverse.cloud) — $
|
|
16
|
+
1. Sign up at [botverse.cloud](https://botverse.cloud) — $5 minimum top-up, no monthly fees
|
|
15
17
|
2. Get an API key or connector URL from your dashboard
|
|
16
18
|
3. Add to your MCP client config
|
|
17
19
|
|
|
@@ -24,7 +26,7 @@ Three tool calls. No AWS. No FFmpeg. No infrastructure.
|
|
|
24
26
|
"mcpServers": {
|
|
25
27
|
"botverse": {
|
|
26
28
|
"command": "npx",
|
|
27
|
-
"args": ["-y", "
|
|
29
|
+
"args": ["-y", "botverse-mcp"],
|
|
28
30
|
"env": {
|
|
29
31
|
"BOTVERSE_API_KEY": "bv_live_..."
|
|
30
32
|
}
|
|
@@ -40,7 +42,7 @@ Or with a connector URL (recommended for claude.ai):
|
|
|
40
42
|
"mcpServers": {
|
|
41
43
|
"botverse": {
|
|
42
44
|
"command": "npx",
|
|
43
|
-
"args": ["-y", "
|
|
45
|
+
"args": ["-y", "botverse-mcp"],
|
|
44
46
|
"env": {
|
|
45
47
|
"BOTVERSE_CONNECTOR_URL": "https://botverse.cloud/mcp?token=bv_sess_..."
|
|
46
48
|
}
|
package/index.js
CHANGED
|
@@ -1,49 +1,72 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* botverse-mcp — stdio bridge for the Botverse MCP server.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Answers `initialize` and `tools/list` locally from tools.json (no key,
|
|
6
|
+
* no network — so the server is introspectable in any sandbox). Proxies
|
|
7
|
+
* actual tool calls to botverse.cloud/mcp, which requires auth.
|
|
8
8
|
*
|
|
9
|
-
* Auth (set one):
|
|
10
|
-
* BOTVERSE_API_KEY=bv_live_...
|
|
9
|
+
* Auth (set one — only needed to *call* tools, not to introspect):
|
|
10
|
+
* BOTVERSE_API_KEY=bv_live_... — API key, sent as Authorization: Bearer
|
|
11
11
|
* BOTVERSE_CONNECTOR_URL=https://... — Full connector URL with ?token=bv_sess_...
|
|
12
|
+
*
|
|
13
|
+
* Compatible with Claude Desktop, Cursor, VS Code, Windsurf, Zed, and any
|
|
14
|
+
* MCP-compatible agent runtime.
|
|
12
15
|
*/
|
|
13
16
|
|
|
14
17
|
const { createInterface } = require("readline");
|
|
18
|
+
const { readFileSync } = require("fs");
|
|
19
|
+
const path = require("path");
|
|
15
20
|
const https = require("https");
|
|
16
21
|
const { URL } = require("url");
|
|
17
22
|
|
|
18
23
|
const CONNECTOR_URL = process.env.BOTVERSE_CONNECTOR_URL;
|
|
19
24
|
const API_KEY = process.env.BOTVERSE_API_KEY;
|
|
20
25
|
const BASE_URL = "https://botverse.cloud/mcp";
|
|
26
|
+
const VERSION = "1.0.4";
|
|
27
|
+
|
|
28
|
+
let TOOLS = [];
|
|
29
|
+
try {
|
|
30
|
+
TOOLS = JSON.parse(readFileSync(path.join(__dirname, "tools.json"), "utf8"));
|
|
31
|
+
} catch {
|
|
32
|
+
TOOLS = []; // introspection still responds, just with an empty tool list
|
|
33
|
+
}
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
35
|
+
const SERVER_INFO = {
|
|
36
|
+
name: "Botverse",
|
|
37
|
+
version: VERSION,
|
|
38
|
+
description:
|
|
39
|
+
"Offload compute-heavy tasks to Botverse — video transcoding and document " +
|
|
40
|
+
"conversion run server-side and return download links. Video (MP4, WebM, " +
|
|
41
|
+
"ProRes, MP3, GIF) and documents (Markdown/HTML/DOCX to DOCX, PDF, HTML, XLSX, TXT).",
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function reply(obj) {
|
|
45
|
+
process.stdout.write(JSON.stringify(obj) + "\n");
|
|
46
|
+
}
|
|
47
|
+
function ok(id, result) {
|
|
48
|
+
reply({ jsonrpc: "2.0", id, result });
|
|
49
|
+
}
|
|
50
|
+
function err(id, message, code = -32603) {
|
|
51
|
+
reply({ jsonrpc: "2.0", id: id ?? null, error: { code, message } });
|
|
28
52
|
}
|
|
29
53
|
|
|
30
54
|
function getTargetUrl() {
|
|
31
55
|
return CONNECTOR_URL || BASE_URL;
|
|
32
56
|
}
|
|
33
|
-
|
|
34
57
|
function getHeaders(bodyLength) {
|
|
35
58
|
const headers = {
|
|
36
59
|
"Content-Type": "application/json",
|
|
60
|
+
Accept: "application/json, text/event-stream",
|
|
37
61
|
"Content-Length": bodyLength,
|
|
38
|
-
"User-Agent": "
|
|
62
|
+
"User-Agent": "botverse-mcp/" + VERSION,
|
|
39
63
|
};
|
|
40
|
-
if (!CONNECTOR_URL && API_KEY) {
|
|
41
|
-
headers["Authorization"] = `Bearer ${API_KEY}`;
|
|
42
|
-
}
|
|
64
|
+
if (!CONNECTOR_URL && API_KEY) headers["Authorization"] = `Bearer ${API_KEY}`;
|
|
43
65
|
return headers;
|
|
44
66
|
}
|
|
45
67
|
|
|
46
|
-
|
|
68
|
+
// Proxy a request to the hosted Botverse MCP endpoint (used for tool calls).
|
|
69
|
+
function proxy(body) {
|
|
47
70
|
return new Promise((resolve, reject) => {
|
|
48
71
|
const raw = JSON.stringify(body);
|
|
49
72
|
const target = new URL(getTargetUrl());
|
|
@@ -54,10 +77,9 @@ function post(body) {
|
|
|
54
77
|
method: "POST",
|
|
55
78
|
headers: getHeaders(Buffer.byteLength(raw)),
|
|
56
79
|
};
|
|
57
|
-
|
|
58
80
|
const req = https.request(options, (res) => {
|
|
59
81
|
let data = "";
|
|
60
|
-
res.on("data", (
|
|
82
|
+
res.on("data", (c) => (data += c));
|
|
61
83
|
res.on("end", () => {
|
|
62
84
|
try {
|
|
63
85
|
resolve(JSON.parse(data));
|
|
@@ -66,9 +88,8 @@ function post(body) {
|
|
|
66
88
|
}
|
|
67
89
|
});
|
|
68
90
|
});
|
|
69
|
-
|
|
70
91
|
req.on("error", reject);
|
|
71
|
-
req.setTimeout(
|
|
92
|
+
req.setTimeout(120000, () => req.destroy(new Error("Request timed out")));
|
|
72
93
|
req.write(raw);
|
|
73
94
|
req.end();
|
|
74
95
|
});
|
|
@@ -80,27 +101,47 @@ rl.on("line", async (line) => {
|
|
|
80
101
|
const trimmed = line.trim();
|
|
81
102
|
if (!trimmed) return;
|
|
82
103
|
|
|
83
|
-
let
|
|
104
|
+
let msg;
|
|
84
105
|
try {
|
|
85
|
-
|
|
106
|
+
msg = JSON.parse(trimmed);
|
|
86
107
|
} catch {
|
|
87
108
|
return; // ignore malformed input
|
|
88
109
|
}
|
|
89
110
|
|
|
111
|
+
const { id, method } = msg;
|
|
112
|
+
|
|
113
|
+
// Notifications (no id) — acknowledge silently per MCP.
|
|
114
|
+
if (id === undefined || id === null) return;
|
|
115
|
+
|
|
116
|
+
// Handle introspection locally — no key, no network.
|
|
117
|
+
if (method === "initialize") {
|
|
118
|
+
return ok(id, {
|
|
119
|
+
protocolVersion: msg.params?.protocolVersion || "2024-11-05",
|
|
120
|
+
capabilities: { tools: {} },
|
|
121
|
+
serverInfo: SERVER_INFO,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (method === "tools/list") {
|
|
125
|
+
return ok(id, { tools: TOOLS });
|
|
126
|
+
}
|
|
127
|
+
if (method === "ping") {
|
|
128
|
+
return ok(id, {});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Everything else (tools/call, etc.) needs auth and goes to the hosted server.
|
|
132
|
+
if (!CONNECTOR_URL && !API_KEY) {
|
|
133
|
+
return err(
|
|
134
|
+
id,
|
|
135
|
+
"Botverse needs credentials to run a job. Set BOTVERSE_API_KEY or " +
|
|
136
|
+
"BOTVERSE_CONNECTOR_URL. Get one at https://botverse.cloud/dashboard/api-keys"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
90
139
|
try {
|
|
91
|
-
const response = await
|
|
92
|
-
|
|
93
|
-
} catch (
|
|
94
|
-
|
|
95
|
-
jsonrpc: "2.0",
|
|
96
|
-
id: message.id ?? null,
|
|
97
|
-
error: {
|
|
98
|
-
code: -32603,
|
|
99
|
-
message: err instanceof Error ? err.message : "Internal error",
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
process.stdout.write(JSON.stringify(errorResponse) + "\n");
|
|
140
|
+
const response = await proxy(msg);
|
|
141
|
+
reply(response);
|
|
142
|
+
} catch (e) {
|
|
143
|
+
err(id, e instanceof Error ? e.message : "Internal error");
|
|
103
144
|
}
|
|
104
145
|
});
|
|
105
146
|
|
|
106
|
-
rl.on("close", () =>
|
|
147
|
+
rl.on("close", () => process.exit(0));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "botverse-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"mcpName": "io.github.MkTurner74/botverse",
|
|
5
5
|
"description": "MCP server for Botverse — video transcoding and document conversion for AI agents. $0.25/transcode · $0.05/convert · No AWS required.",
|
|
6
6
|
"main": "index.js",
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/
|
|
15
|
+
"url": "https://github.com/MkTurner74/botverse-mcp.git"
|
|
16
16
|
},
|
|
17
17
|
"homepage": "https://botverse.cloud",
|
|
18
18
|
"bugs": {
|
|
19
|
-
"url": "https://github.com/
|
|
19
|
+
"url": "https://github.com/MkTurner74/botverse-mcp/issues"
|
|
20
20
|
},
|
|
21
21
|
"keywords": [
|
|
22
22
|
"mcp",
|
package/server.json
CHANGED
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
"name": "io.github.MkTurner74/botverse",
|
|
4
4
|
"description": "Video transcoding and document conversion for AI agents. Per-job billing, no infrastructure.",
|
|
5
5
|
"repository": {
|
|
6
|
-
"url": "https://github.com/
|
|
6
|
+
"url": "https://github.com/MkTurner74/botverse-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.4",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "botverse-mcp",
|
|
14
|
-
"version": "1.0.
|
|
14
|
+
"version": "1.0.4",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|
package/tools.json
ADDED
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "get_upload_url",
|
|
4
|
+
"description": "Get a presigned PUT URL to upload any file — video, audio, or document (markdown, HTML, DOCX, etc.). The URL expires in 15 minutes. PUT raw file bytes directly to the URL. After upload, pass the object_key to transcode_video (for video) or convert_file (for documents).",
|
|
5
|
+
"inputSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"filename": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Original filename including extension, e.g. report.md or footage.mp4"
|
|
11
|
+
},
|
|
12
|
+
"content_type": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "MIME type. Video: \"video/mp4\". Documents: \"text/markdown\", \"text/html\", \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", \"text/plain\"."
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"required": [
|
|
18
|
+
"filename",
|
|
19
|
+
"content_type"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"outputSchema": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"properties": {
|
|
25
|
+
"upload_url": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Presigned HTTPS PUT URL. Send raw file bytes as the request body."
|
|
28
|
+
},
|
|
29
|
+
"object_key": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "storage object key — pass this to transcode_video or convert_file."
|
|
32
|
+
},
|
|
33
|
+
"expires_in": {
|
|
34
|
+
"type": "number",
|
|
35
|
+
"description": "Seconds until the upload URL expires (900 = 15 minutes)."
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"required": [
|
|
39
|
+
"upload_url",
|
|
40
|
+
"object_key",
|
|
41
|
+
"expires_in"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"annotations": {
|
|
45
|
+
"readOnlyHint": false,
|
|
46
|
+
"destructiveHint": false,
|
|
47
|
+
"idempotentHint": false,
|
|
48
|
+
"openWorldHint": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "transcode_from_url",
|
|
53
|
+
"description": "Offload a video or audio transcode to Botverse using a public URL — no upload step needed. Accepts Dropbox, Google Drive, OneDrive, SharePoint, and Box share links directly — pass the share URL as-is, no manual conversion needed. Also works with any direct HTTPS download URL (CDN, object storage, etc.). Limited to 2 GB. Returns a job_id immediately. IMPORTANT: tell the user the job_id right away so they can track it. Then poll get_job_status every 5 seconds. Large video files (>100 MB) can take 5–15 minutes — keep polling until status is 'complete' or 'failed', no matter how many polls it takes. Never give up early. Wallet debited on completion. Use options.start_time and options.duration to trim — e.g. start_time='00:01:00', duration=120 for a 2-minute clip.",
|
|
54
|
+
"inputSchema": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"properties": {
|
|
57
|
+
"source_url": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"description": "Public HTTPS URL of the source video or audio file."
|
|
60
|
+
},
|
|
61
|
+
"output_format": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"enum": [
|
|
64
|
+
"mp4",
|
|
65
|
+
"webm",
|
|
66
|
+
"mov_prores",
|
|
67
|
+
"mp3",
|
|
68
|
+
"gif"
|
|
69
|
+
],
|
|
70
|
+
"description": "Target output format. One of: mp4 (H.264), webm (VP9), mov_prores (ProRes 422), mp3 (audio extraction), gif."
|
|
71
|
+
},
|
|
72
|
+
"options": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"description": "Optional encoding parameters. All are optional.",
|
|
75
|
+
"properties": {
|
|
76
|
+
"start_time": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"description": "Seek to this position before encoding, e.g. '00:01:30' or '90'. Useful for trimming long files."
|
|
79
|
+
},
|
|
80
|
+
"duration": {
|
|
81
|
+
"type": "number",
|
|
82
|
+
"description": "Encode only this many seconds of content after start_time. Use with start_time to extract a clip."
|
|
83
|
+
},
|
|
84
|
+
"width": {
|
|
85
|
+
"type": "number",
|
|
86
|
+
"description": "Output width in pixels. Height scales proportionally if only width is set."
|
|
87
|
+
},
|
|
88
|
+
"height": {
|
|
89
|
+
"type": "number",
|
|
90
|
+
"description": "Output height in pixels. Width scales proportionally if only height is set."
|
|
91
|
+
},
|
|
92
|
+
"bitrate": {
|
|
93
|
+
"type": "string",
|
|
94
|
+
"description": "Video bitrate, e.g. '2M' for 2 Mbps."
|
|
95
|
+
},
|
|
96
|
+
"framerate": {
|
|
97
|
+
"type": "number",
|
|
98
|
+
"description": "Output frame rate, e.g. 24 or 30."
|
|
99
|
+
},
|
|
100
|
+
"audio_bitrate": {
|
|
101
|
+
"type": "string",
|
|
102
|
+
"description": "Audio bitrate for mp3 output, e.g. '128k' or '320k'."
|
|
103
|
+
},
|
|
104
|
+
"h264_profile": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"enum": [
|
|
107
|
+
"baseline",
|
|
108
|
+
"main",
|
|
109
|
+
"high"
|
|
110
|
+
],
|
|
111
|
+
"description": "H.264 encoding profile for mp4 output. baseline = max device compatibility (mobile, streaming, older hardware). main = balanced (default). high = best quality for modern playback."
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"required": [
|
|
117
|
+
"source_url",
|
|
118
|
+
"output_format"
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
"outputSchema": {
|
|
122
|
+
"type": "object",
|
|
123
|
+
"properties": {
|
|
124
|
+
"job_id": {
|
|
125
|
+
"type": "string",
|
|
126
|
+
"description": "Unique identifier for this job. Pass to get_job_status and get_download_url."
|
|
127
|
+
},
|
|
128
|
+
"status": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"enum": [
|
|
131
|
+
"queued",
|
|
132
|
+
"processing"
|
|
133
|
+
],
|
|
134
|
+
"description": "Initial job state — always queued or processing immediately after submission."
|
|
135
|
+
},
|
|
136
|
+
"estimated_seconds": {
|
|
137
|
+
"type": "number",
|
|
138
|
+
"description": "Rough estimated processing time in seconds. Actual time may vary."
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"required": [
|
|
142
|
+
"job_id",
|
|
143
|
+
"status"
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
"annotations": {
|
|
147
|
+
"readOnlyHint": false,
|
|
148
|
+
"destructiveHint": false,
|
|
149
|
+
"idempotentHint": false,
|
|
150
|
+
"openWorldHint": true
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"name": "transcode_video",
|
|
155
|
+
"description": "Offload a video transcode to Botverse — encoding runs server-side so you can continue with other tasks. Returns a job_id immediately. Source must be ≤ 10 minutes and ≤ 5 GB. Poll get_job_status every 5 seconds until 'complete', then get_download_url. Wallet debited on completion.",
|
|
156
|
+
"inputSchema": {
|
|
157
|
+
"type": "object",
|
|
158
|
+
"properties": {
|
|
159
|
+
"object_key": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"description": "storage object key returned by get_upload_url."
|
|
162
|
+
},
|
|
163
|
+
"output_format": {
|
|
164
|
+
"type": "string",
|
|
165
|
+
"enum": [
|
|
166
|
+
"mp4",
|
|
167
|
+
"webm",
|
|
168
|
+
"mov_prores",
|
|
169
|
+
"mp3",
|
|
170
|
+
"gif"
|
|
171
|
+
],
|
|
172
|
+
"description": "Target output format. One of: mp4 (H.264), webm (VP9), mov_prores (ProRes 422), mp3 (audio extraction), gif."
|
|
173
|
+
},
|
|
174
|
+
"options": {
|
|
175
|
+
"type": "object",
|
|
176
|
+
"description": "Optional encoding parameters. All are optional.",
|
|
177
|
+
"properties": {
|
|
178
|
+
"start_time": {
|
|
179
|
+
"type": "string",
|
|
180
|
+
"description": "Seek to this position before encoding, e.g. '00:01:30' or '90'."
|
|
181
|
+
},
|
|
182
|
+
"duration": {
|
|
183
|
+
"type": "number",
|
|
184
|
+
"description": "Encode only this many seconds of content after start_time."
|
|
185
|
+
},
|
|
186
|
+
"width": {
|
|
187
|
+
"type": "number",
|
|
188
|
+
"description": "Output width in pixels."
|
|
189
|
+
},
|
|
190
|
+
"height": {
|
|
191
|
+
"type": "number",
|
|
192
|
+
"description": "Output height in pixels."
|
|
193
|
+
},
|
|
194
|
+
"bitrate": {
|
|
195
|
+
"type": "string",
|
|
196
|
+
"description": "Video bitrate, e.g. '2M'."
|
|
197
|
+
},
|
|
198
|
+
"framerate": {
|
|
199
|
+
"type": "number",
|
|
200
|
+
"description": "Output frame rate, e.g. 24 or 30."
|
|
201
|
+
},
|
|
202
|
+
"audio_bitrate": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"description": "Audio bitrate for mp3 output, e.g. '128k'."
|
|
205
|
+
},
|
|
206
|
+
"h264_profile": {
|
|
207
|
+
"type": "string",
|
|
208
|
+
"enum": [
|
|
209
|
+
"baseline",
|
|
210
|
+
"main",
|
|
211
|
+
"high"
|
|
212
|
+
],
|
|
213
|
+
"description": "H.264 encoding profile for mp4 output. baseline = max device compatibility. main = balanced (default). high = best quality for modern playback."
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"required": [
|
|
219
|
+
"object_key",
|
|
220
|
+
"output_format"
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
"outputSchema": {
|
|
224
|
+
"type": "object",
|
|
225
|
+
"properties": {
|
|
226
|
+
"job_id": {
|
|
227
|
+
"type": "string",
|
|
228
|
+
"description": "Unique identifier for this job. Pass to get_job_status and get_download_url."
|
|
229
|
+
},
|
|
230
|
+
"status": {
|
|
231
|
+
"type": "string",
|
|
232
|
+
"enum": [
|
|
233
|
+
"queued",
|
|
234
|
+
"processing"
|
|
235
|
+
],
|
|
236
|
+
"description": "Initial job state — always queued or processing immediately after submission."
|
|
237
|
+
},
|
|
238
|
+
"estimated_seconds": {
|
|
239
|
+
"type": "number",
|
|
240
|
+
"description": "Rough estimated processing time in seconds. Actual time may vary."
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"required": [
|
|
244
|
+
"job_id",
|
|
245
|
+
"status"
|
|
246
|
+
]
|
|
247
|
+
},
|
|
248
|
+
"annotations": {
|
|
249
|
+
"readOnlyHint": false,
|
|
250
|
+
"destructiveHint": false,
|
|
251
|
+
"idempotentHint": false,
|
|
252
|
+
"openWorldHint": true
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"name": "get_job_status",
|
|
257
|
+
"description": "Poll the status of a transcode or convert job. Call every 5 seconds until status is 'complete' or 'failed'. Status 'queued' or 'processing' is normal — large files take 5–15 minutes. Keep polling indefinitely until a terminal status is reached. Do not stop polling after a fixed number of attempts.",
|
|
258
|
+
"inputSchema": {
|
|
259
|
+
"type": "object",
|
|
260
|
+
"properties": {
|
|
261
|
+
"job_id": {
|
|
262
|
+
"type": "string",
|
|
263
|
+
"description": "Job ID returned by transcode_video, transcode_from_url, convert_file, convert_from_url, or convert_content."
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
"required": [
|
|
267
|
+
"job_id"
|
|
268
|
+
]
|
|
269
|
+
},
|
|
270
|
+
"outputSchema": {
|
|
271
|
+
"type": "object",
|
|
272
|
+
"properties": {
|
|
273
|
+
"job_id": {
|
|
274
|
+
"type": "string",
|
|
275
|
+
"description": "The job identifier."
|
|
276
|
+
},
|
|
277
|
+
"status": {
|
|
278
|
+
"type": "string",
|
|
279
|
+
"enum": [
|
|
280
|
+
"queued",
|
|
281
|
+
"processing",
|
|
282
|
+
"complete",
|
|
283
|
+
"failed"
|
|
284
|
+
],
|
|
285
|
+
"description": "Current job state."
|
|
286
|
+
},
|
|
287
|
+
"progress_pct": {
|
|
288
|
+
"type": "number",
|
|
289
|
+
"description": "Encoding progress 0–100. Only present while status is 'processing'."
|
|
290
|
+
},
|
|
291
|
+
"output_key": {
|
|
292
|
+
"type": "string",
|
|
293
|
+
"description": "storage object key of the completed output. Present when status is 'complete'. Pass to get_download_url."
|
|
294
|
+
},
|
|
295
|
+
"cost_usd": {
|
|
296
|
+
"type": "number",
|
|
297
|
+
"description": "Amount debited from the wallet on completion, in USD."
|
|
298
|
+
},
|
|
299
|
+
"error_message": {
|
|
300
|
+
"type": "string",
|
|
301
|
+
"description": "Human-readable error description. Present when status is 'failed'."
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
"required": [
|
|
305
|
+
"job_id",
|
|
306
|
+
"status"
|
|
307
|
+
]
|
|
308
|
+
},
|
|
309
|
+
"annotations": {
|
|
310
|
+
"readOnlyHint": true,
|
|
311
|
+
"destructiveHint": false,
|
|
312
|
+
"idempotentHint": true,
|
|
313
|
+
"openWorldHint": true
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"name": "get_download_url",
|
|
318
|
+
"description": "Get a presigned HTTPS URL to download the completed output file. Call after get_job_status returns 'complete'. URL expires in 24 hours.",
|
|
319
|
+
"inputSchema": {
|
|
320
|
+
"type": "object",
|
|
321
|
+
"properties": {
|
|
322
|
+
"job_id": {
|
|
323
|
+
"type": "string",
|
|
324
|
+
"description": "Job ID from transcode_video, transcode_from_url, or any convert tool."
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
"required": [
|
|
328
|
+
"job_id"
|
|
329
|
+
]
|
|
330
|
+
},
|
|
331
|
+
"outputSchema": {
|
|
332
|
+
"type": "object",
|
|
333
|
+
"properties": {
|
|
334
|
+
"download_url": {
|
|
335
|
+
"type": "string",
|
|
336
|
+
"description": "Presigned HTTPS GET URL for the output file. Valid for 24 hours."
|
|
337
|
+
},
|
|
338
|
+
"filename": {
|
|
339
|
+
"type": "string",
|
|
340
|
+
"description": "Suggested filename for the downloaded file including extension."
|
|
341
|
+
},
|
|
342
|
+
"expires_at": {
|
|
343
|
+
"type": "string",
|
|
344
|
+
"description": "ISO 8601 timestamp when the download URL expires."
|
|
345
|
+
},
|
|
346
|
+
"size_bytes": {
|
|
347
|
+
"type": "number",
|
|
348
|
+
"description": "File size of the output in bytes."
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
"required": [
|
|
352
|
+
"download_url",
|
|
353
|
+
"filename",
|
|
354
|
+
"expires_at"
|
|
355
|
+
]
|
|
356
|
+
},
|
|
357
|
+
"annotations": {
|
|
358
|
+
"readOnlyHint": true,
|
|
359
|
+
"destructiveHint": false,
|
|
360
|
+
"idempotentHint": true,
|
|
361
|
+
"openWorldHint": true
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
"name": "get_wallet_balance",
|
|
366
|
+
"description": "Check the current prepaid wallet balance for this Botverse account. Use before large batch jobs to confirm sufficient funds.",
|
|
367
|
+
"inputSchema": {
|
|
368
|
+
"type": "object",
|
|
369
|
+
"properties": {},
|
|
370
|
+
"required": []
|
|
371
|
+
},
|
|
372
|
+
"outputSchema": {
|
|
373
|
+
"type": "object",
|
|
374
|
+
"properties": {
|
|
375
|
+
"balance_usd": {
|
|
376
|
+
"type": "number",
|
|
377
|
+
"description": "Current wallet balance in USD."
|
|
378
|
+
},
|
|
379
|
+
"auto_refill_enabled": {
|
|
380
|
+
"type": "boolean",
|
|
381
|
+
"description": "Whether automatic wallet top-up is enabled."
|
|
382
|
+
},
|
|
383
|
+
"refill_threshold_usd": {
|
|
384
|
+
"type": "number",
|
|
385
|
+
"description": "Balance threshold in USD that triggers an auto-refill, if enabled."
|
|
386
|
+
},
|
|
387
|
+
"refill_amount_usd": {
|
|
388
|
+
"type": "number",
|
|
389
|
+
"description": "Amount in USD added on each auto-refill, if enabled."
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
"required": [
|
|
393
|
+
"balance_usd",
|
|
394
|
+
"auto_refill_enabled"
|
|
395
|
+
]
|
|
396
|
+
},
|
|
397
|
+
"annotations": {
|
|
398
|
+
"readOnlyHint": true,
|
|
399
|
+
"destructiveHint": false,
|
|
400
|
+
"idempotentHint": true,
|
|
401
|
+
"openWorldHint": false
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"name": "convert_from_url",
|
|
406
|
+
"description": "Offload a document conversion to Botverse — runs server-side in seconds, returns a download link, and frees you to continue with other tasks while it processes. Use this when the source document is at a public URL — including Dropbox, Google Drive, OneDrive, SharePoint, and Box share links (pass the share URL as-is). If you already have the content as a string, use convert_content instead — no upload step needed. Supported inputs: md, html, rst, txt, docx. Supported outputs: docx (Word), pdf, html, txt, md, rst, xlsx (tables extracted). Returns a job_id immediately. Poll get_job_status every 5s until 'complete', then get_download_url. Flat fee $0.05 per file.",
|
|
407
|
+
"inputSchema": {
|
|
408
|
+
"type": "object",
|
|
409
|
+
"properties": {
|
|
410
|
+
"source_url": {
|
|
411
|
+
"type": "string",
|
|
412
|
+
"description": "Public HTTPS URL of the source document."
|
|
413
|
+
},
|
|
414
|
+
"output_format": {
|
|
415
|
+
"type": "string",
|
|
416
|
+
"enum": [
|
|
417
|
+
"docx",
|
|
418
|
+
"html",
|
|
419
|
+
"txt",
|
|
420
|
+
"md",
|
|
421
|
+
"rst",
|
|
422
|
+
"pdf",
|
|
423
|
+
"xlsx"
|
|
424
|
+
],
|
|
425
|
+
"description": "Target format: docx | html | txt | md | rst | pdf | xlsx"
|
|
426
|
+
}
|
|
427
|
+
},
|
|
428
|
+
"required": [
|
|
429
|
+
"source_url",
|
|
430
|
+
"output_format"
|
|
431
|
+
]
|
|
432
|
+
},
|
|
433
|
+
"outputSchema": {
|
|
434
|
+
"type": "object",
|
|
435
|
+
"properties": {
|
|
436
|
+
"job_id": {
|
|
437
|
+
"type": "string",
|
|
438
|
+
"description": "Unique identifier for this job. Pass to get_job_status and get_download_url."
|
|
439
|
+
},
|
|
440
|
+
"status": {
|
|
441
|
+
"type": "string",
|
|
442
|
+
"enum": [
|
|
443
|
+
"queued",
|
|
444
|
+
"processing"
|
|
445
|
+
],
|
|
446
|
+
"description": "Initial job state — always queued or processing immediately after submission."
|
|
447
|
+
},
|
|
448
|
+
"estimated_seconds": {
|
|
449
|
+
"type": "number",
|
|
450
|
+
"description": "Rough estimated processing time in seconds. Actual time may vary."
|
|
451
|
+
}
|
|
452
|
+
},
|
|
453
|
+
"required": [
|
|
454
|
+
"job_id",
|
|
455
|
+
"status"
|
|
456
|
+
]
|
|
457
|
+
},
|
|
458
|
+
"annotations": {
|
|
459
|
+
"readOnlyHint": false,
|
|
460
|
+
"destructiveHint": false,
|
|
461
|
+
"idempotentHint": false,
|
|
462
|
+
"openWorldHint": true
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
"name": "convert_file",
|
|
467
|
+
"description": "Offload a document conversion to Botverse using an already-uploaded file. Workflow: (1) call get_upload_url to get a presigned upload URL, (2) PUT the raw file bytes to that URL, (3) call convert_file with the object_key — Botverse handles the rest server-side. Returns a job_id immediately so you can continue with other tasks while conversion runs. Supported inputs: md, html, rst, txt, docx. Supported outputs: docx, pdf, html, txt, md, rst, xlsx. Poll get_job_status until complete, then get_download_url. Flat fee $0.05 per file.",
|
|
468
|
+
"inputSchema": {
|
|
469
|
+
"type": "object",
|
|
470
|
+
"properties": {
|
|
471
|
+
"object_key": {
|
|
472
|
+
"type": "string",
|
|
473
|
+
"description": "The object_key returned by get_upload_url."
|
|
474
|
+
},
|
|
475
|
+
"output_format": {
|
|
476
|
+
"type": "string",
|
|
477
|
+
"enum": [
|
|
478
|
+
"docx",
|
|
479
|
+
"html",
|
|
480
|
+
"txt",
|
|
481
|
+
"md",
|
|
482
|
+
"rst",
|
|
483
|
+
"pdf",
|
|
484
|
+
"xlsx"
|
|
485
|
+
],
|
|
486
|
+
"description": "Target format: docx | html | txt | md | rst | pdf | xlsx"
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
"required": [
|
|
490
|
+
"object_key",
|
|
491
|
+
"output_format"
|
|
492
|
+
]
|
|
493
|
+
},
|
|
494
|
+
"outputSchema": {
|
|
495
|
+
"type": "object",
|
|
496
|
+
"properties": {
|
|
497
|
+
"job_id": {
|
|
498
|
+
"type": "string",
|
|
499
|
+
"description": "Unique identifier for this job. Pass to get_job_status and get_download_url."
|
|
500
|
+
},
|
|
501
|
+
"status": {
|
|
502
|
+
"type": "string",
|
|
503
|
+
"enum": [
|
|
504
|
+
"queued",
|
|
505
|
+
"processing"
|
|
506
|
+
],
|
|
507
|
+
"description": "Initial job state — always queued or processing immediately after submission."
|
|
508
|
+
},
|
|
509
|
+
"estimated_seconds": {
|
|
510
|
+
"type": "number",
|
|
511
|
+
"description": "Rough estimated processing time in seconds. Actual time may vary."
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
"required": [
|
|
515
|
+
"job_id",
|
|
516
|
+
"status"
|
|
517
|
+
]
|
|
518
|
+
},
|
|
519
|
+
"annotations": {
|
|
520
|
+
"readOnlyHint": false,
|
|
521
|
+
"destructiveHint": false,
|
|
522
|
+
"idempotentHint": false,
|
|
523
|
+
"openWorldHint": true
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
"name": "submit_workflow",
|
|
528
|
+
"description": "Submit a multi-step workflow to the Botverse workflow engine. Steps execute in dependency order; parallel branches (multiple steps with the same depends_on) run simultaneously. Returns a workflow_id immediately — poll get_workflow_status every 5–10 seconds until terminal. Requires auto-refill to be enabled at botverse.cloud/dashboard/billing to prevent mid-workflow balance failures. Workflow definition uses BWDL (Botverse Workflow Definition Language) — schema at botverse.cloud/schemas/workflow/v1.json.",
|
|
529
|
+
"inputSchema": {
|
|
530
|
+
"type": "object",
|
|
531
|
+
"properties": {
|
|
532
|
+
"definition": {
|
|
533
|
+
"type": "object",
|
|
534
|
+
"description": "BWDL workflow definition. Must include workflow_id (string) and steps (array). Each step needs id, tool, and inputs."
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
"required": [
|
|
538
|
+
"definition"
|
|
539
|
+
]
|
|
540
|
+
},
|
|
541
|
+
"outputSchema": {
|
|
542
|
+
"type": "object",
|
|
543
|
+
"properties": {
|
|
544
|
+
"workflow_id": {
|
|
545
|
+
"type": "string",
|
|
546
|
+
"description": "Unique workflow identifier. Pass to get_workflow_status."
|
|
547
|
+
},
|
|
548
|
+
"status": {
|
|
549
|
+
"type": "string",
|
|
550
|
+
"description": "Initial status: QUEUED or PROCESSING."
|
|
551
|
+
},
|
|
552
|
+
"step_count": {
|
|
553
|
+
"type": "number",
|
|
554
|
+
"description": "Number of steps in the workflow."
|
|
555
|
+
},
|
|
556
|
+
"already_exists": {
|
|
557
|
+
"type": "boolean",
|
|
558
|
+
"description": "True if this workflow_id was already submitted — idempotent resubmit."
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
"required": [
|
|
562
|
+
"workflow_id",
|
|
563
|
+
"status"
|
|
564
|
+
]
|
|
565
|
+
},
|
|
566
|
+
"annotations": {
|
|
567
|
+
"readOnlyHint": false,
|
|
568
|
+
"destructiveHint": false,
|
|
569
|
+
"idempotentHint": true,
|
|
570
|
+
"openWorldHint": true
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
"name": "get_workflow_status",
|
|
575
|
+
"description": "Get the current status of a workflow and all its steps. Each call may advance the workflow by dispatching steps whose dependencies have completed. Poll every 5–10 seconds until status is COMPLETED, FAILED, PARTIALLY_FAILED, or CANCELLED.",
|
|
576
|
+
"inputSchema": {
|
|
577
|
+
"type": "object",
|
|
578
|
+
"properties": {
|
|
579
|
+
"workflow_id": {
|
|
580
|
+
"type": "string",
|
|
581
|
+
"description": "Workflow ID returned by submit_workflow."
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
"required": [
|
|
585
|
+
"workflow_id"
|
|
586
|
+
]
|
|
587
|
+
},
|
|
588
|
+
"outputSchema": {
|
|
589
|
+
"type": "object",
|
|
590
|
+
"properties": {
|
|
591
|
+
"workflow_id": {
|
|
592
|
+
"type": "string"
|
|
593
|
+
},
|
|
594
|
+
"status": {
|
|
595
|
+
"type": "string",
|
|
596
|
+
"enum": [
|
|
597
|
+
"QUEUED",
|
|
598
|
+
"PROCESSING",
|
|
599
|
+
"COMPLETED",
|
|
600
|
+
"PARTIALLY_FAILED",
|
|
601
|
+
"FAILED",
|
|
602
|
+
"CANCELLED"
|
|
603
|
+
]
|
|
604
|
+
},
|
|
605
|
+
"total_cost_usd": {
|
|
606
|
+
"type": "number"
|
|
607
|
+
},
|
|
608
|
+
"steps": {
|
|
609
|
+
"type": "array",
|
|
610
|
+
"description": "Array of step status objects."
|
|
611
|
+
},
|
|
612
|
+
"completed_at": {
|
|
613
|
+
"type": "string",
|
|
614
|
+
"description": "ISO timestamp when workflow reached terminal state."
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
"required": [
|
|
618
|
+
"workflow_id",
|
|
619
|
+
"status"
|
|
620
|
+
]
|
|
621
|
+
},
|
|
622
|
+
"annotations": {
|
|
623
|
+
"readOnlyHint": true,
|
|
624
|
+
"destructiveHint": false,
|
|
625
|
+
"idempotentHint": true,
|
|
626
|
+
"openWorldHint": true
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
"name": "cancel_workflow",
|
|
631
|
+
"description": "Cancel an in-progress workflow. All queued and dispatched steps are marked CANCELLED. Completed steps are not reversed. You are only billed for steps that completed before cancellation.",
|
|
632
|
+
"inputSchema": {
|
|
633
|
+
"type": "object",
|
|
634
|
+
"properties": {
|
|
635
|
+
"workflow_id": {
|
|
636
|
+
"type": "string",
|
|
637
|
+
"description": "Workflow ID to cancel."
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
"required": [
|
|
641
|
+
"workflow_id"
|
|
642
|
+
]
|
|
643
|
+
},
|
|
644
|
+
"outputSchema": {
|
|
645
|
+
"type": "object",
|
|
646
|
+
"properties": {
|
|
647
|
+
"workflow_id": {
|
|
648
|
+
"type": "string"
|
|
649
|
+
},
|
|
650
|
+
"cancelled": {
|
|
651
|
+
"type": "boolean"
|
|
652
|
+
},
|
|
653
|
+
"status": {
|
|
654
|
+
"type": "string"
|
|
655
|
+
}
|
|
656
|
+
},
|
|
657
|
+
"required": [
|
|
658
|
+
"workflow_id",
|
|
659
|
+
"cancelled"
|
|
660
|
+
]
|
|
661
|
+
},
|
|
662
|
+
"annotations": {
|
|
663
|
+
"readOnlyHint": false,
|
|
664
|
+
"destructiveHint": false,
|
|
665
|
+
"idempotentHint": true,
|
|
666
|
+
"openWorldHint": false
|
|
667
|
+
}
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
"name": "convert_content",
|
|
671
|
+
"description": "Offload an inline document conversion to Botverse — pass the content directly as a string. ONLY use this tool for content you generated yourself (e.g. Markdown you just wrote). HARD LIMIT: content must be under 10,000 characters. If the content is longer than 10,000 characters, or came from an uploaded or external file, DO NOT use this tool — tell the user to make the file available at a public URL (Google Drive share link, Dropbox, object storage, etc.) and use convert_from_url instead. Supported inputs: md, html, rst, txt (plain text), docx (base64). Supported outputs: docx (Word), pdf, html, txt, md, rst, xlsx. Flat fee $0.05 per file.",
|
|
672
|
+
"inputSchema": {
|
|
673
|
+
"type": "object",
|
|
674
|
+
"properties": {
|
|
675
|
+
"content": {
|
|
676
|
+
"type": "string",
|
|
677
|
+
"description": "The file content as a plain text string (for md, html, rst, txt) or base64-encoded bytes (for docx)."
|
|
678
|
+
},
|
|
679
|
+
"input_format": {
|
|
680
|
+
"type": "string",
|
|
681
|
+
"enum": [
|
|
682
|
+
"md",
|
|
683
|
+
"html",
|
|
684
|
+
"rst",
|
|
685
|
+
"txt",
|
|
686
|
+
"docx"
|
|
687
|
+
],
|
|
688
|
+
"description": "Source format of the content."
|
|
689
|
+
},
|
|
690
|
+
"output_format": {
|
|
691
|
+
"type": "string",
|
|
692
|
+
"enum": [
|
|
693
|
+
"docx",
|
|
694
|
+
"html",
|
|
695
|
+
"txt",
|
|
696
|
+
"md",
|
|
697
|
+
"rst",
|
|
698
|
+
"pdf",
|
|
699
|
+
"xlsx"
|
|
700
|
+
],
|
|
701
|
+
"description": "Target format: docx | html | txt | md | rst | pdf | xlsx"
|
|
702
|
+
},
|
|
703
|
+
"encoding": {
|
|
704
|
+
"type": "string",
|
|
705
|
+
"enum": [
|
|
706
|
+
"text",
|
|
707
|
+
"base64"
|
|
708
|
+
],
|
|
709
|
+
"description": "Encoding of the content field. Defaults to \"text\". Use \"base64\" for binary inputs like .docx."
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
"required": [
|
|
713
|
+
"content",
|
|
714
|
+
"input_format",
|
|
715
|
+
"output_format"
|
|
716
|
+
]
|
|
717
|
+
},
|
|
718
|
+
"outputSchema": {
|
|
719
|
+
"type": "object",
|
|
720
|
+
"properties": {
|
|
721
|
+
"job_id": {
|
|
722
|
+
"type": "string",
|
|
723
|
+
"description": "Unique identifier for this job. Pass to get_job_status and get_download_url."
|
|
724
|
+
},
|
|
725
|
+
"status": {
|
|
726
|
+
"type": "string",
|
|
727
|
+
"enum": [
|
|
728
|
+
"queued",
|
|
729
|
+
"processing"
|
|
730
|
+
],
|
|
731
|
+
"description": "Initial job state — always queued or processing immediately after submission."
|
|
732
|
+
},
|
|
733
|
+
"estimated_seconds": {
|
|
734
|
+
"type": "number",
|
|
735
|
+
"description": "Rough estimated processing time in seconds. Actual time may vary."
|
|
736
|
+
}
|
|
737
|
+
},
|
|
738
|
+
"required": [
|
|
739
|
+
"job_id",
|
|
740
|
+
"status"
|
|
741
|
+
]
|
|
742
|
+
},
|
|
743
|
+
"annotations": {
|
|
744
|
+
"readOnlyHint": false,
|
|
745
|
+
"destructiveHint": false,
|
|
746
|
+
"idempotentHint": false,
|
|
747
|
+
"openWorldHint": true
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
]
|