katto-mcp 0.5.2 → 0.5.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.
Files changed (3) hide show
  1. package/README.md +32 -4
  2. package/index.mjs +12 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # katto-mcp
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/katto-mcp.svg)](https://www.npmjs.com/package/katto-mcp)
4
+ [![npm downloads](https://img.shields.io/npm/dm/katto-mcp.svg)](https://www.npmjs.com/package/katto-mcp)
5
+ [![license](https://img.shields.io/npm/l/katto-mcp.svg)](./LICENSE)
6
+ [![MCP Registry](https://img.shields.io/badge/MCP%20Registry-io.github.miracleweasel%2Fkatto--mcp-blue)](https://registry.modelcontextprotocol.io)
7
+
3
8
  **The AI video clipping MCP server.** Turn long videos into scored, captioned, vertical 9:16 short clips from any MCP client (Claude, Cursor, Claude Code, ChatGPT, VS Code, and other conformant clients). Drop in a YouTube link, a podcast, or a Twitch VOD and get publish-ready shorts back through natural conversation.
4
9
 
5
10
  Powered by [Katto](https://katto.tech), an AI video clipper that turns long-form video (podcasts, interviews, streams, webinars) into short-form clips for TikTok, Reels and YouTube Shorts. Katto is a flat-priced, no-credits alternative to tools like OpusClip: one 25-video quota covers videos up to 90 minutes each, with the API and MCP included on every paid plan (not gated behind an enterprise tier).
@@ -10,7 +15,7 @@ Ask your agent something like *"clip the best moments from this podcast and refr
10
15
 
11
16
  - find the strongest 30 to 90 second moments in a long video and score each clip 0 to 100 on Hook, Flow, Value and Trend,
12
17
  - reframe to vertical 9:16 with face tracking, split-screen for two speakers, and stacked layouts for gaming,
13
- - burn word-by-word animated captions (99 languages) and optionally dub into 8 languages,
18
+ - burn animated captions (auto-captioned in 99 languages via Whisper large-v3; word-by-word timing in 41 of them, sentence-level in the rest) and optionally dub into 8 languages,
14
19
  - and hand back publish-ready MP4 files plus SRT caption urls.
15
20
 
16
21
  Typical uses: repurpose a YouTube video into shorts, turn a podcast episode into clips, cut highlights from a Twitch VOD, or convert a long interview into vertical social posts.
@@ -43,7 +48,22 @@ For Cursor, CI and scripts. Create an API key at **[katto.tech/dashboard/api-key
43
48
 
44
49
  The hosted endpoint above also accepts `Authorization: Bearer sk_live_...` directly for key-based clients.
45
50
 
46
- ## Tools (15)
51
+ ## Install per client
52
+
53
+ **Claude Code** (hosted, OAuth):
54
+ ```bash
55
+ claude mcp add --transport http katto https://mcp.katto.tech/mcp
56
+ ```
57
+
58
+ **Claude Desktop** — Settings → Connectors → *Add custom connector* → `https://mcp.katto.tech/mcp`, then sign in. (Or add the `npx` block above to `claude_desktop_config.json`.)
59
+
60
+ **Cursor** — Settings → MCP → *Add* → paste the `npx` JSON block above (uses `KATTO_API_KEY`).
61
+
62
+ **VS Code** (MCP extension) — add the same `npx` block to your MCP settings, or point it at the hosted URL if your client supports remote OAuth servers.
63
+
64
+ **ChatGPT** (Developer mode / connectors) — add a custom connector with URL `https://mcp.katto.tech/mcp`.
65
+
66
+ ## Tools
47
67
 
48
68
  Clipping:
49
69
  - **`katto_create_clip_job(url, config?)`** clip a long video (YouTube, Twitch, Vimeo, Rumble, Zoom, Dailymotion). Returns a job id.
@@ -62,7 +82,7 @@ Account and reference:
62
82
  - **`katto_get_usage()`** your plan and remaining monthly video quota.
63
83
  - **`katto_get_account()`** the connected account, this key's scopes, and quota.
64
84
  - **`katto_get_brand_kit()`** your saved brand kits (colors, caption font, layout, watermark).
65
- - **`katto_get_webhook_secret()`** your webhook signing secret and how to verify signed callbacks.
85
+ - **`katto_get_webhook_secret()`** your webhook signing secret and how to verify signed callbacks (returns a secret — treat it like a credential).
66
86
  - **`katto_list_sources()`** the video platforms Katto can clip from, with an example url each.
67
87
  - **`katto_list_clip_lengths()`** the valid target clip-length buckets.
68
88
 
@@ -77,6 +97,12 @@ Jobs draw from your Katto plan's monthly video quota (25 on Creator, 2 on Free),
77
97
 
78
98
  Full docs: **[katto.tech/docs/api](https://katto.tech/docs/api)**
79
99
 
100
+ ## Security & data
101
+
102
+ - **Hosted auth is OAuth 2.1** — the API key is never written to your disk, and you can revoke a connected client anytime from your Katto account settings.
103
+ - **Local auth uses a scoped `sk_live_` key** you create yourself; keys can be read-only, and the npx server only sends it to `KATTO_API_URL` (default `katto.tech`) over HTTPS.
104
+ - `katto_get_webhook_secret` returns a signing secret — handle it like any credential; it is only needed to verify inbound webhook signatures.
105
+
80
106
  ## Also listed on
81
107
 
82
108
  - npm: [katto-mcp](https://www.npmjs.com/package/katto-mcp)
@@ -96,4 +122,6 @@ Example prompts:
96
122
  2. "Check the status of my last clipping job and give me the download links for the finished clips."
97
123
  3. "Take clip 2 from that job, dub it into Spanish and re-render it with the Bold caption style."
98
124
 
99
- MIT
125
+ ## License
126
+
127
+ MIT — see [LICENSE](./LICENSE).
package/index.mjs CHANGED
@@ -15,12 +15,19 @@ import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprot
15
15
  const API_URL = (process.env.KATTO_API_URL || "https://katto.tech").replace(/\/$/, "");
16
16
  const API_KEY = process.env.KATTO_API_KEY;
17
17
 
18
+ // NOTE: we intentionally do NOT exit when the key is missing. The server must be
19
+ // able to start and answer tools/list WITHOUT a key so that MCP directory/aggregator
20
+ // sandboxes (Glama, mcp.so, ...) can enumerate the tools — otherwise they show
21
+ // "0 tools". Nothing runs unauthenticated: the key is enforced at call time in api()
22
+ // below, so tools/list is public but every tool CALL still requires a valid key.
18
23
  if (!API_KEY) {
19
- console.error("[katto-mcp] KATTO_API_KEY is required. Create one at https://katto.tech/dashboard/api-keys");
20
- process.exit(1);
24
+ console.error("[katto-mcp] No KATTO_API_KEY set — tools/list works, but calling any tool requires a key. Create one at https://katto.tech/dashboard/api-keys");
21
25
  }
22
26
 
23
27
  async function api(path, init = {}) {
28
+ if (!API_KEY) {
29
+ throw new Error("KATTO_API_KEY is required to call Katto tools. Create one at https://katto.tech/dashboard/api-keys and set it in your MCP client config.");
30
+ }
24
31
  const res = await fetch(`${API_URL}${path}`, {
25
32
  ...init,
26
33
  headers: {
@@ -45,7 +52,7 @@ const TOOLS = [
45
52
  name: "katto_create_clip_job",
46
53
  description:
47
54
  "Submit a long video (YouTube, Twitch, Vimeo, Rumble, Zoom, Dailymotion) to Katto. Returns a job id; " +
48
- "the clips finish asynchronously in ~5-7 min. Poll katto_get_job with the id until status is 'completed'.",
55
+ "the clips finish asynchronously. Poll katto_get_job with the id until status is 'completed'.",
49
56
  inputSchema: {
50
57
  type: "object",
51
58
  properties: {
@@ -243,7 +250,7 @@ const ANNOTATIONS = {
243
250
  // Agent-facing descriptions (when to call, returns, errors, quota cost). Served
244
251
  // on tools/list — identical across all sources, enriching the terser inline text.
245
252
  const DESCRIPTIONS = {
246
- katto_create_clip_job: "Submit a long video (YouTube, Twitch, Vimeo, Rumble, Zoom, Dailymotion) for clipping. Consumes 1 video from your monthly quota — check katto_get_usage first. Clips are produced asynchronously (~5-7 min); returns a job id, then poll katto_get_job until status is 'completed'. Fails if the URL is unsupported or the video is over 90 minutes.",
253
+ katto_create_clip_job: "Submit a long video (YouTube, Twitch, Vimeo, Rumble, Zoom, Dailymotion) for clipping. Consumes 1 video from your monthly quota — check katto_get_usage first. Clips are produced asynchronously; returns a job id, then poll katto_get_job until status is 'completed'. Fails if the URL is unsupported or the video is over 90 minutes.",
247
254
  katto_get_job: "Read-only. Get the status, progress and clips of a job by id. When status is 'completed', 'clips' holds the finished 9:16 MP4 urls and caption (SRT) urls; while processing, clips is empty. Returns 404 for an unknown id.",
248
255
  katto_list_jobs: "Read-only. List your recent jobs, newest first. Paginate with 'cursor' (pass the previous next_cursor); optional 'status' filter. Returns { jobs: [{id, status, source, created_at, completed_at}], next_cursor }.",
249
256
  katto_get_clips: "Read-only convenience: just the finished clips of a job (9:16 MP4 urls + caption SRT urls + title + virality score). Returns an empty list while the job is still processing.",
@@ -283,7 +290,7 @@ const CLIP_LENGTHS = [
283
290
  { value: '90_180', label: '90 to 180 seconds' },
284
291
  ];
285
292
 
286
- const server = new Server({ name: "katto", version: "0.5.2" }, { capabilities: { tools: {} } });
293
+ const server = new Server({ name: "katto", version: "0.5.4" }, { capabilities: { tools: {} } });
287
294
 
288
295
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS_LISTED }));
289
296
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "katto-mcp",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "mcpName": "io.github.miracleweasel/katto-mcp",
5
5
  "description": "AI video clipping MCP server: turn long videos, podcasts and Twitch VODs into scored, captioned 9:16 shorts from Claude, Cursor, ChatGPT and any MCP client.",
6
6
  "type": "module",