clipbait 1.7.0 → 1.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 (3) hide show
  1. package/README.md +1 -1
  2. package/index.js +39 -25
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -22,7 +22,7 @@ Opens Clipbait so you can copy your key, then installs a `/clipbait` slash comma
22
22
  ### Claude Code
23
23
 
24
24
  ```bash
25
- claude mcp add --transport http clipbait https://app.clipbait.ai/api/mcp/cbk_live_your_key_here
25
+ claude mcp add --transport http clipbait https://app.clipbait.ai/api/mcp --header "X-API-Key: cbk_live_your_key_here"
26
26
  ```
27
27
 
28
28
  ### Cursor / Cline / Windsurf / manual
package/index.js CHANGED
@@ -13,6 +13,7 @@ const path = require("path");
13
13
  const CFG = path.join(os.homedir(), ".clipbait.json");
14
14
  const BASE = (process.env.CLIPBAIT_API_URL || "https://app.clipbait.ai/api").replace(/\/$/, "");
15
15
  const KEY_PAGE = "https://app.clipbait.ai/me";
16
+ const MCP_URL = "https://app.clipbait.ai/api/mcp";
16
17
 
17
18
  // Shown whenever there's no usable key. Written so an AI agent can relay it
18
19
  // verbatim to the user and they'll know exactly what to do.
@@ -74,12 +75,14 @@ function prompt(question) {
74
75
  // reads MCP servers from ~/.claude.json under projects[cwd].mcpServers (local
75
76
  // scope) and, when present, a top-level mcpServers (user scope) — we write
76
77
  // both so it shows up regardless of which directory Claude opens in.
77
- function writeMcpConfig(mcpUrl) {
78
+ function writeMcpConfig(key) {
78
79
  const cfgPath = path.join(os.homedir(), ".claude.json");
79
80
  let cfg;
80
81
  try { cfg = JSON.parse(fs.readFileSync(cfgPath, "utf8")); }
81
82
  catch { return false; } // no/unreadable config → caller prints manual steps
82
- const entry = { type: "http", url: mcpUrl };
83
+ // Key travels in an X-API-Key header, not the URL path — keeps it out of the
84
+ // URL (and request logs). It still lives in the config file, same as any MCP.
85
+ const entry = { type: "http", url: MCP_URL, headers: { "X-API-Key": key } };
83
86
  cfg.mcpServers = cfg.mcpServers || {};
84
87
  cfg.mcpServers.clipbait = entry;
85
88
  const cwd = process.cwd();
@@ -143,55 +146,66 @@ function writeDesktopConfig(key) {
143
146
  // Interactive one-command setup. Grabs the key (from arg / saved / by opening
144
147
  // the browser and prompting), installs the /clipbait command, and connects the
145
148
  // MCP server to Claude Code and Claude Desktop.
149
+ // Print the exact config for the user/agent to apply, WITHOUT touching any
150
+ // files. Used in non-interactive contexts (an agent ran this): silently
151
+ // rewriting global AI-tool config there reads as a supply-chain attack, so we
152
+ // stay transparent and let the caller apply it with full visibility.
153
+ function printManualConfig(key) {
154
+ console.log("\nTo connect Clipbait, apply one of these (nothing was written — you're not in an interactive terminal):\n");
155
+ console.log("Claude Code:");
156
+ console.log(` claude mcp add --transport http clipbait ${MCP_URL} --header "X-API-Key: ${key}"\n`);
157
+ console.log("Claude Desktop / Cursor / Cline / Windsurf — add to the MCP config:");
158
+ console.log(` ${JSON.stringify({ mcpServers: { clipbait: { command: "npx", args: ["-y", "clipbait@latest", "mcp"], env: { CLIPBAIT_API_KEY: key } } } })}\n`);
159
+ console.log(`Tip: run \`npx clipbait@latest\` in a real terminal to apply this automatically.\n`);
160
+ }
161
+
146
162
  async function runSetup(providedKey) {
163
+ const interactive = !!process.stdin.isTTY;
147
164
  let key = providedKey && providedKey.startsWith("cbk_") ? providedKey : loadKey();
148
165
 
149
166
  if (!key) {
167
+ if (!interactive) { console.error(NEED_KEY); process.exit(1); }
150
168
  console.log("\n⚡ Let's connect Clipbait to Claude.");
151
- if (!process.stdin.isTTY) {
152
- // No interactive terminal (e.g. an AI agent ran this). Print the full
153
- // guidance so the agent can pass it straight to the user.
154
- console.error(NEED_KEY);
155
- process.exit(1);
156
- }
157
169
  console.log(`\nOpening ${KEY_PAGE} so you can copy your API key…`);
158
170
  openBrowser(KEY_PAGE);
159
171
  key = (await prompt("\nPaste your API key (starts with cbk_) and press Enter:\n> ")).trim();
160
172
  }
173
+ if (!key || !key.startsWith("cbk_")) { console.error(NEED_KEY); process.exit(1); }
161
174
 
162
- if (!key || !key.startsWith("cbk_")) {
163
- console.error(NEED_KEY);
164
- process.exit(1);
165
- }
175
+ // Non-interactive (agent / pipe): don't silently modify global config. Print
176
+ // it and let the caller apply it with consent.
177
+ if (!interactive) { printManualConfig(key); return; }
178
+
179
+ // Interactive: announce exactly what will change BEFORE writing anything, so
180
+ // it never looks like a package quietly registering itself.
181
+ console.log("\n⚡ Clipbait setup will make these changes on this machine:");
182
+ console.log(" • save your API key to ~/.clipbait.json");
183
+ console.log(" • install a /clipbait slash command (~/.claude/commands/clipbait.md)");
184
+ console.log(" • register the Clipbait MCP server in Claude Code (~/.claude.json)");
185
+ console.log(" • register it in Claude Desktop, if installed\n");
166
186
 
167
187
  fs.writeFileSync(CFG, JSON.stringify({ apiKey: key }, null, 2));
168
- const mcpUrl = "https://app.clipbait.ai/api/mcp/" + key;
169
188
 
170
- // 1) Install the /clipbait slash command for Claude Code.
171
189
  const cmdDir = path.join(os.homedir(), ".claude", "commands");
172
190
  fs.mkdirSync(cmdDir, { recursive: true });
173
191
  fs.writeFileSync(path.join(cmdDir, "clipbait.md"), SLASH_COMMAND);
174
192
  console.log("✓ Installed the /clipbait command for Claude Code");
175
193
 
176
- // 2) Register the MCP server with Claude Code. Prefer editing the config
177
- // file directly (works everywhere); fall back to the `claude` CLI, then to
178
- // printing manual steps.
179
- if (writeMcpConfig(mcpUrl)) {
180
- console.log("✓ Connected the Clipbait MCP server to Claude Code");
194
+ if (writeMcpConfig(key)) {
195
+ console.log("✓ Registered the Clipbait MCP server in Claude Code");
181
196
  } else {
182
197
  const { spawnSync } = require("child_process");
183
- const r = spawnSync("claude", ["mcp", "add", "--transport", "http", "clipbait", mcpUrl], { stdio: "ignore" });
198
+ const r = spawnSync("claude", ["mcp", "add", "--transport", "http", "clipbait", MCP_URL, "--header", `X-API-Key: ${key}`], { stdio: "ignore" });
184
199
  if (!r.error && r.status === 0) {
185
- console.log("✓ Connected the Clipbait MCP server to Claude Code");
200
+ console.log("✓ Registered the Clipbait MCP server in Claude Code");
186
201
  } else {
187
- console.log("• Couldn't auto-connect the MCP server. Add it manually:");
188
- console.log(" claude mcp add --transport http clipbait " + mcpUrl);
202
+ console.log("• Couldn't auto-register the MCP server. Add it manually:");
203
+ console.log(` claude mcp add --transport http clipbait ${MCP_URL} --header "X-API-Key: ${key}"`);
189
204
  }
190
205
  }
191
206
 
192
- // 3) Also configure Claude Desktop if installed (stdio server → download_clip).
193
207
  if (writeDesktopConfig(key)) {
194
- console.log("✓ Connected Clipbait to Claude Desktop (quit + reopen it to load)");
208
+ console.log("✓ Registered Clipbait in Claude Desktop (quit + reopen it to load)");
195
209
  }
196
210
 
197
211
  console.log("\n🎬 Done! Restart Claude Code, then type:\n /clipbait https://youtube.com/watch?v=…\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clipbait",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Clipbait CLI + MCP server — turn any video into viral clips, and auto-clip live streams, from your terminal or any AI agent.",
5
5
  "bin": { "clipbait": "index.js" },
6
6
  "type": "commonjs",